skip navigational linksPJRC
Shopping Cart Checkout Shipping Cost Download Website
Home MP3 Player 8051 Tools All Projects PJRC Store Site Map
You are here: MP3 Player News And Updates Project History Search PJRC

PJRC Store
Main Board, $150
LCD & Pushbuttons, $42
LCD/Backlight/PB, $77
IDE Cable, $9
Complete Parts List
MP3 Player
Main Page
Detailed Info
User Photo Gallery
Connecting The Board
Firmware Download
Side Projects
Technical Docs
Freq. Asked Questions
FAQ #2
News And Updates
Recent News
selected Project History

History

December 28, 2001: I have (finally) set up a Bugzilla Bug Tracking Database for this project. This thing is still new and hasn't been used much, so please be careful and let me know if anything about it seems to not work properly. The Bugzilla database can be used to report bugs and to request new features.

December 17, 2001: It's official, firmware release 0.6.4. It's been quite some time since the last release and a lot has changed. This code should be much more stable than all the previous 0.6.x versions. I also added some minor features back to the old non-SIMM version (now 0.1.3), so it's auto-detect IDE master/slave and will work with those older buggy drives. Please give 0.6.4 a try. Your feedback, tested with your hard drive and your SIMM, would really help.

As usual, I'm behind on answering emails. Now that this firmware release is out, I'll try to catch up tonight and tommorrow.

December 14, 2001: I did more work in the firmware and FPGA over the last couple days, and it is now committed to CVS. Dave's snapshot page should have it soon. Here's a compiled image with all these changes.

  1. Updated the rev to 0.6.4 (in anticipation of an official release later this weekend). The startup message says "December 14, 2001", so you can easily tell if you are running the code with these changes.
  2. Changed the 8051 address decoding inside the FPGA to use a 2-stage pipeline. The Xilinx software was complaining about some long logic delays in there, which shouldn't be a problem due to the 8051's timings, but the Xilinx static timing analysis tool (and router) can't know that. The only "know" about the 14.7456 MHz clock inside the FPGA. I have no idea if this will make any real difference, but it can't hurt.
  3. Changed the timing constraints used for the placement and routing inside the FPGA.
  4. Restored the tri-state feature on the IDE pins. If you pull the IDE_DISABLE pin low, all the IDE pins will go high impedence. The firmware will almost certainly crash when the DRAM and IDE are inaccessible, so be sure to reboot before you release the IDE_DISABLE.
  5. Added Dave Johnson's idea to dynamically adjust the STA013's TONE_ATTN parameter. This allows the player to acheive the full voltage range of the DAC without losing the tone controls. It sounds like it works, but there may be slight clipping with some settings of the tone low/high filter frequencies. If you discover problems with this, be prepared to provide the MP3 file and the exact settings you were using.
  6. The default volume setting is now -20 dB. It was previously -12 dB, but now the whole thing is quite a bit louder due to the dynamic TONE_ATTN.
  7. The ID3 tag info is no longer printed when there isn't actually an ID3 tag. This prevents binary garbage that can mess with the character sets of your terminal emulator software.
  8. The DRAM test utility only runs once, instead of looping endlessly (or a long time) when the DRAM fails the test.

The other interesting thing that happened today was a discussion on the SDCC developer mail list (which I am involved with). SDCC generates very inefficient code for initializing static and global variables. It's looking like this will improve soon.

December 12, 2001: Last night I worked yet again on the DRAM controller, this time on the 8051-interface section. I redesigned the address latching circuitry (using the 8051's ALE to enable flip-flops instead of using it as a clock). This appears to greatly improve the stability of the player. My test board has been running for a little over 11 hours continuously since I made this change.

These "hardware" changes are inside the FPGA, so your board will get these changes when you upgrade the firmware. No physical changes are made to the board, and the changes will work on all three board revisions.

I committed this new DRAM controller to the CVS server this morning, so Dave's nightly build page should have a compiled image with the new DRAM controller sometime tommorrow. (I'll put a copy on the yahoo group so you can get it now). Please give this new code a try and let me know if it is stable or crashes on your board. It's still too early to tell for sure, but it's looking pretty good. The board I'm using now is the worst one I have... it's never managed to run any of the 0.6.x firmware for more than a 4-5 hours, and with this new code it's been playing without problems since I made the change 11 hours ago.

Tom also committed a large group of cleanups and improvements to the code, mostly in the display and non-volatile parameter handling. There will probably be some more fixes over the next couple days. I am particularly interested in integrating Dave Johnson's idea to allow full max volume output while still having the tone controls. If things are looking stable, I'll make an official release (probably 0.6.5) sometime during the weekend.

If you've been following the yahoo group discussions, you've probably seen talk about officially ending the display beta test. The display firmware seems to be very stable. The display bugs appear to have been completely solved by the changes I committed on August 8th. Tom added several new features to the display board's firmware in August and September. The last bug was fixed on October 7, and there have not been any changes since. All displays that have been shipped in November and December have the latest firmware and do not need an upgrade.

Robin and I are planning to send free display upgrade chips to everyone who has the original display firmware. This upgrade will fix the shift-by-two-pixels bug and other minor pixel corruption, and it'll also update the display with all of Tom's performance enchancing code, which greatly reduces the flicker when the screen is redrawn and reduces the bandwidth used on the serial port.

I'll post details when we're ready to send the chips. We're planning to have a special page with a form to request the chip (since many people's addresses may have changed). PJRC will pay for the chip and shipping via low-cost postal mail for everyone who has the old firmware.

December 11, 2001: Today I spent quite a bit of time investigating some bugs reported by "Marco", who apparantly is attempting to add cdrom support to the code. He ran into all sorts of strange (and fairly reproducable) problems. He didn't send a copy of his code, but after a while I managed to reproduce the problem and ultimately get to the bottom of it. I was hoping this might lead to a fix for the current bug that causes the firmware to crash after some time, but Marco's problems turned out to be related to some tricky aspects to using 16 bit PIO access to the IDE interface. The current firmware only uses PIO access as startup. I added some description of the 16 bit PIO issues to the memory map page.

December 10, 2001: It looks like subscribers are started receiving the January issue of Poptronics, which includes an article about this MP3 player project. The article shows the rev A board, as the new rev C board was not ready in time for their publication deadlines, and rev B wasn't documented well enough for the article. All three revisions to the board have made improvements to the power supply, while the MP3 player part has remained the same.

If you're a Poptronics reader and you plan to build this project, please use the newer rev C design, which makes some significant improvements to the power supply section. Rev C printed circuit board artwork and assembly instructions are on-line. Saddly, I have not had time to draw a nice schematic for the new rev C board, but I do have a hand-drawn schematic of the new power supply section, so I'll get that scanned soon and put it on-line (and eventually draw a nice schematic like the other ones). If, for some reason, you really want to build rev A, don't forget to check the Rev A Errata page. The Poptronics article probably doesn't mention these errata items, which is entirely my fault.

November 4, 2001: This weekend PJRC.COM moved to new hosting at Verio. The new server has a lot of bandwidth, so pages should load much faster for anyone with DSL, cable or other fast internet access. Dial-up users may even notice an improvement at busy times. Hopefully the days of DSL users bringing the site to its knees with Teleport Pro will soon be a distant memory. Verio should also be much more reliable that our old ISP (inetarena.com), who's had many outages and performance problems since its founder sold the company to netrover.com.

The DNS was switched Saturday afternoon, and since then the new server has slowly been taking more of the traffic. A few people are still accessing the old server. If you're seeing this message, your nameserver has updated with the new IP number and you're accessing the new server. Our email was down for part of Friday and Saturday, so if you sent Robin or me a message and it bounced, the email should be working again. CVS is still not loaded on the new server, but it should be running sometime tommorrow. I'm hoping to wrap up all this server transition stuff Monday night and spend the rest of the week working on much-needed updates to many of the web pages.

Moving the entire website and getting everything to work again has been quite a bit of work over the last few days. It's quite possible I missed something. If you notice anything broken, please send me an email.

We have several more assembled boards and unassembled kits available. We actually ran out of kits in the middle of last week and the last assembled board from the first batch was shipped on Friday. The good news is that we've got several more in stock just in time!

October 29, 2001: We've finally cleared all the backorders for mp3 player boards and kits. There's actually a few rev C boards and one kit left at the moment, and we're no longer reserving them for people who selected Western Union or PayPal but haven't responded to emails over the last week. It feels great to finally be caught up! We'll have the next batch of boards ready on Nov 5, so if we run out this week it'll only be until next Monday.

This weekend I created the Rev C kit assembly diagrams. At the bottom of those pages is a download for a hi-res copy of all 12 assembly diagrams, which looks good when printed on a laser printer. This time, I put some extra work into getting all the parts very clearly labeled with bold text and all the other parts nicely gray'd out to make it easier to read, even when printed without color. If you're one of the people who's recently received a Rev C kit, please contact me if anything is unclear in these diagrams. Robin and I both double checked them, but it is always possible I could have made an error or omission.

The Rev C layout artwork is also on-line. I'm still working to update the schematic for Rev C, and hopefully it will appear sometime this week. I also have the images ready for a schematic and layout of the pushbutton adaptor board that comes with the display. I know several people have requested this... it will be up very soon. I'm trying to fill in the missing web pages (here and on other parts of the web site) over the next several days. Once these are written/drawn, I'm planning to get back into working on the firmware in a serious way.

We've been in contact with Gernsback Publications very recently, and it looks like they will run a story about this little mp3 player project in the January issue of Poptronics Magazine (formerly Popular Electronics). The material in the magazine will cover the Rev A board, since we didn't have all the info needed for Rev C in time for their deadline. The story in the magazine won't have much that isn't already here on the web site, but it should be able to reach a lot of folks who don't know about the site. I'm told that the January issue hits the news stands on December 11, a couple weeks before Christmas. If you want a copy, that'd be a good time to look for it. I'm told that the mp3 player will appear alongside some antenna project on the cover of the magazine. We sent them a board to take photos, but I do not know exactly what they will do.

We are planning to increase the price of the unassembled kit and the display, but only slightly. Don't panic... nothing has changed yet, and nothing will change until at least November 15 to allow anyone who's "thinking about it" to order at today's prices. The unassembled kit will go to $150, which is the same price as the assembled and tested board. The main reason for this is because we spend a similar amount of time putting the parts into the nicely labeled bags as we do putting them into the circuit board, but the tech support on kits is much harder. On the display, we're going to increase to $42 (adding only $5). This is my fault... I underestimated the cost of building the custom cables, particularily the ribbon cable that needs to be hand soldered on all 17 conductors. All the other parts will remain the same price, at least for the forseeable future.

Well, that's a bunch of things for one news update. I think that more or less covers everything. Now that we're finally caught up on these mp3 players and the 8051 development board, I'll be doing some much-needed updates to the web site and then quite a bit of work on the firmware.

October 21, 2001: We finally have the first small batch of Rev C boards and kits ready. Here is the photo of the first Rev C board:

Here is a larger photo (120k). We'll be shipping boards and kits tommorrow, and this first small batch should cover most, if not all of the backorders. I'll be posting info about the new rev C to the technical docs section over the next week, but for now Robin and I are tired and need to take a little break!

October 10, 2001: Well, I've missed the deadline to get the first 20 rev C boards made by Saturday (Oct 13), but it looks very good for getting them sometime next week. One really positive thing that's come out of this long process is that I've finally drawn a reasonable schematic for the first board. Well, it's missing the pushbuttons and serial interface, but that'll be easy to add. Getting all those connections checked was a lot of work, as you can see from that image. I know there's a good number of people (several are students) who've been waiting for the schematic for quite a while, so enjoy. Rev C makes only a couple minor tweaks to the main schematic, so it'll be relatively easy to get a complete rev C schematic up by the time we're shipping boards.

Also, I should mention that I've fallen behind in answering emails (worse that usual...) Please be patient, I will try to answer them all, probably next week while the boards are getting fabricated and we're making the inevitable last-minute orders for a few missing parts.

October 4, 2001: It probably seems like I've dropped off the face of the earth... no updates to this page, not much happening with the firmware lately, ran out of mp3 player circuit boards, etc. Well, here's a bit about what's been going on lately.

We ran out of boards about 5-6 weeks ago, and once more I was faced with the decision, "should I just make more of the exact same board, or should I try to improve the design". As you may know, I've never been 100% happy with the power supply part of the board. Rev A worked, though not nearly as efficiently as I wanted. Rev A also has a 4.5 to 6 volt input, and it was easy to damage the board by applying more than 7 volts to this input. I made some minor changes to create rev B with a sturdy 6 to 10 volt input (in addition to the 10-15 volt input), and the change reduced the heating in the TIP102 transistor. Still, it seem like it ought to be possible to do better.

Well, it isn't easy. Over the last several weeks I've made multiple attempts that turned out to be dismal failures at a better power supply. I was about to give up. I took one more shot at it, and finally a result that I think is pretty good has come about. Here's a photo of the prototype:

prototype construction photo

This supply uses a lot of the same parts as rev B, but the performance is considerably improved. The higher voltage input is still 10 to 15 volts, with protection from the nasty spikes from a car's alternator. The low voltage input is now 4 to 10 volts, which means rev C will be able to run from four AA batteries like rev A, but will be sturdy like rev B. Rev C's battery input will be much more efficient that either rev A or rev B... I wanted to be close to 100% efficient, but that's nearly impossible for a supply that can step up or step down as needed. I made many attempts to get really high efficiency, some using lots of expensive parts, but in the end none worked really well. I talked with a guy who's an expert at switching power supplies, but all his ideas revolved around complex custom transformers and inductors. I tried contacting some of the companies that make these. Most won't touch it for under 5000 parts/year, and those that will are very expensive for qty 100-200. So it looks like the standard parts (Cooper/Coiltronics) will have to do. I think this rev C supply is a good compromise and it keeps the cost and total size about the same as rev B.

One of the major changes is a new PWM control chip. This new part (TL5001) includes a sort start limiter, which will eliminate the problem were the board can trip the current limiting that's built into many lab bench power supplies (not an issue for batteries and "wall warts"). The new switching supply makes only +5 volts, and a LP2950 linear regulator makes the 3.3 volts. Creating only +5 volts allows the supply to make better use of the transformer, and I switched to a somewhat smaller transformer (less magnetic material = lower losses is the core, which more than makes up for the small loss in the LP2950 for 3.3 volts). I also did a little trick to use the flyback voltage to create a little higher drive voltage for the mosfet, which really helps reduce the heating in the mosfet (and improve efficiency) when the supply is run from only 4 volts. There's also an undervoltage lock-out and a max duty cycle limiter so that the supply acts much more gracefully as the battery voltage falls below 4 volts. I also overhauled the circuit that muxes the 12 volt and battery inputs and protect from car alternator noise while preventing the battery from seeing destructive overcharging. The rev A and rev B versions used a diode in series with the battery, which really cuts into the battery's run time. The rev C design uses a P-channel mosfet (it's on the bottom of the prototype board) to eliminate the loss from that diode. I think that's most of the changes... all in all, it's quite an improvement over rev A and rev B. Though not as ambitious as my first couple (failed) attempts, I think it's pretty good and it'll fit into the existing board size without changing the cost of the board much (we'll keep the price the same at $150).

A major frustration in this project has been the CAD software. The program I used for rev A and rev B is having a lot of trouble (corrupted files, bogus gerber output, etc). It really sucks to have to redraw an entire board with this many connections, but that's exactly what I had to do. Luckily I have access to some better software now, which has its own set of minor problems, but at least it seems to have a solid database and file format behind it. I'm going to avoid mentioning names, but I will say that the really problematic program was one of the really inexpensive packages. I guess you get what you pay for...

So the big question is when will these rev C board be available. I wish I had an exact date. Today the new transformers finally arrived. We're still missing some of the important parts, but have a small number of them left over from rev B. I talked with the board fab company and they can get us a small number of boards in a hurry (for an extra fee, of course). We're going to try to get the first rev C boards and kits shipped on Oct 15. I know we have a few folks waiting who're using the board as part of a project with an urgent deadline. We're going to try to ship to them and the people who've been waiting more than 2 weeks. We'll get the rest of the boards and have them built later in the month... so hopefully we can have all the backlog taken care of before Halloween (Oct 31).

I probably won't manage to get much done on the firmware until the boards and kits are sitting in stock and all the orders are shipped. One exception to this is the display beta test. Tom did a lot of work on the display firmware a couple months ago, and I made some small changes to fix the 2-pixel-shift bug and other random drawing bugs. Tom's new code includes some changes to make the display update better with less communication bandwidth from the player, but there's one more bug in this new code that prevents it from really improving the redraw responsiveness. Tom has been on a vacation for a couple weeks but recently returned. He'll probably look into this soon, and either way I'll do some work with the display firmware so that when we have the board again later this month, we'll have displays with the new debugged and improved code on them (the display is not easily upgradable like the player is).

So that's more or less where the project is at. I am alive and well, but quite busy trying to get everything put together to finally have rev C boards available. Hopefully next month we'll have plenty of boards again and I can get back to working on the firmware and doing much-needed updates to the web site.

August 24, 2001: It's been a few weeks since I've added any updates here. I'm going to try to get an update up here at least once a week.

It's been almost exactly 2 months since the firmware development was moved to CVS, and during that time several people have come on board and really helped fill out a lot of the player's features.

Ian did quite a bit of work to add items to the display, including interactive tone controls. Zach added code that scans all the directories on the drive. I overhauled the device drivers to speed this up, and Matthew has done quite a bit of work to optimize this. He also began some of the initial coding to be able to read .m3u files, but much remains to be done there. Matthew also made several valliant attempts to make that code non-recursive (allowing almost limitless subdirectory depth to be scanned), but that's a difficult task. I did some optimizing and improved the recursive version, so we can at least scan 5-6 levels deep. Somewhere in there I spent a very frustrating week or so chasing after the bug that makes the player lock up eventually, but it still ellludes me. Early on, Ian had written some code to find ID3 tags. I fixed a couple bugs, and then Ian, Chris, Matthew and others did quite a lot with ID3 tags, and today's firmware displays the ID3 info on the LCD. Zac joined the group and fixed a long-standing bug in my I2C driver code. Zac then added an nice elapsed time display, where "--:--" had always been, and he did some cleanups and improvements to the ID3 parsing code. Matthew did some more work to try to process .m3u playlist files, but this really needs more support from the drivers. I added a driver function to allow memory mapping 4k sections files, but more library-level support is needed for parsing before .m3u processing can happen in a reasonable efficient manner. Chris added more play modes, sequential in just one directory or the whole drive, random in directory or whole drive, etc. Chris also added a resume feature, where the player will usually remember where it was in the list and start there again when it is used again after a shutdown. Tom has been working on adding some cool features to the display board code. I did some testing and fixed the shift-by-two-pixels bug in the display, and Tom has added a freeze/unfreeze feature that should make updates flicker less. Tom also put in support for scrolling directly in the display, which will cut down on the excessive data trasfer to the display. I believe this is most of what's happened in the last month, but it's hard to recall everything in detail... If I've missed something that anyone contributed, please let me know.

So what's next? Well, it's becoming clear that soon there needs to be a new official firmware rev, even if we can't call it "stable".

In firmware development, probably the next major thing will be an overhaul of the main playback state machine. This is no small task. Eventually this would enable playing files larger than the SIMM, and probably also use the avaialble memory better, perhaps to read ahead into the next file if there is a lot of memory, perhaps to read the first part of many upcoming and/or previous files to have rapid response to the pushbuttons.

There's also the task of reading .m3u playlists, ID3v2 tags, fast forward/rewind, more LCD stuff... the list goes on and on. Actually, there is a file in the firmware source called "wish_list.txt" which is more or less the official list of requested features. This list is writable only to developers with CVS commit access, mainly so that ideas are filtered through developers who have an idea of what is and isn't feasible. All developers are welcome to add to the list (or remove as things are implemented).

On the less technical front, we ran out of circuit boards a few days ago. We're working to get more made, but it will be a couple weeks. It'll also consume some of my time, so I won't be doing as much work on the firmware until they're done.

The final thing that's going on it pjrc.com will be moving to a different ISP. There will be a couple weeks of overlap, so with some luck things will go smoothly with the DNS and there won't be any down-time (I hope). The new server will be at a data center with very high speed connections to the net, so viewing pjrc.com should become noticably faster if you have a broadband internet service. It should also be much more reliable that what we've been using.

August 5, 2001: Today I spent the whole day writing a dir_read_fast function which is an attempt to make a much faster directory read. If you've tried 0.6.3.3 or the recent CVS versions, you know that they scan all the subdirectories on the drive (up to some level, currently 3 deep in today's CVS code). Today this is slow. This new fast directory read should make a big difference. Right now it's very new and not used by the directory scanning code (it's API is a bit different).

Also, if you haven't been keeping up with the latest CVS code, about a week ago Matthew and Ian got ID3 tag display working. All of the 8 lines of the display now do something. I want to make an official release on the firmware page, but it will have to wait as I spent the entire day doing the new fast directory reading code.

July 25, 2001: Quite a bit has happened in the last 24 hours! I haven't had much time to work on the project for the last few weeks, and the firmware hit a limit called DSEG overflow which prevented anyone from doing much. A couple days ago I wrote a perl script that checks the DSEG usage and I made a bunch of small improvements to make more DSEG space.

Matthew added display of which directory is being played. Ian committed some bug fixes. Quite some time ago Ian wrote code to read the ID3 tag, but until last night it wasn't finding the correct place in the file. I fixed that, and then Matthew picked it up and added parsing and display of the ID3 tag info (title, album, artist). There's been some fiddling with optimizing the directory scanning code, and it was broken for a while but looks like it may be fixed now.

Things are really moving. If you want to try out this cool new stuff, grab the source code from CVS, or download from Jim's automatically updated compiled images. If there aren't any major bugs, I'll make rev 0.6.3.4 over the weekend.

June 30, 2001: Zach added code that plays all the MP3 files on the drive, not just the root directory!

Ian added adjustment of the bass and treble roll-off frequencies.

I've been quite busy lately had haven't even been able to keep up with my email and the yahoo group. Today I included Zach's new code. I probably won't have much time for this project until July 4. If you've sent me an email and I haven't answered, please try to wait until the 4th to remind me.

June 26, 2001: I stayed up late and did some investigation into why some newer SIMMs are incompatible with the player. The short story is that there is both good news and bad news. First, the good news is it looks like I'll be able to improve the SIMM detection code to make these newer SIMMs work properly. But, the bad news is that the hardware was designed around the older style of SIMM and only a portion of newer SIMMs will be usable with the player.

Here are some photos of both types of SIMMs. I have an archived copy of the datasheet for the older SIMM type. When I designed the board, this was the only datasheet I could find on-line. The four chips on that newer SIMM shown below are Samsung KM48C8000, and I was able to find someone's old copy of the datasheet (google is great!). Using the datasheet for the chips and some reverse engineering with an ohm meter, I was able to learn a bit about these newer SIMMs. Using today's firmware (0.6.3.2), this newer 32 meg SIMM is detected as 8 megs, and the player attempts to use it and crashes (because only 4 megs is actually usable).

32 meg SIMM with 8 chips on each side
Older Style (compatible) 32 meg SIMM, 16 chips (both sides), 24 pins per chip

32 meg SIMM with 4 chips on front side only
Newer Style (incompatible) 32 meg SIMM, 4 chips, 32 pins per chip

The devil is in the details, and I'll describe what's going on a bit. 72 pin SIMMs have a 32 bit data bus. The bus on the player is only 16 bits, so the board connects the upper and lower 16 bits together and then tries to tell the SIMM to only read/write 16 bits at a time. SIMMs have four row control lines, four column control lines, and between 10 to 13 address pins.

DRAM memory is arranged in a matrix. Other easy-to-use memories like SRAM and EPROM are also built this way, but you can't "see" the arrangement because there is some nice circuitry inside that takes care of those details. With DRAM, you have to deal with the arrangement of the matrix inside. This is where the row and column lines come into play. To access a particular memory location in a single DRAM chip, you have to specify the address in two parts. First, you drive the address pins with the number of the row you want and assert the row control pin. A short time later (68 ns on this board), you drive the address pins with the column you want and assert the column control signal. There's also a write enable bit. If it's high when the column control was asserted, the DRAM sends data to the player, and if was low it stores whatever data the player drove onto its data pins. This sequence of events to access the DRAM is done automatically every time the processor reads or writes the memory and also when one of the DMA channels needs to read. There is also another type of operation called refresh, which happens every 15.6 µs.

When multiple DRAM chips are assembled together on a SIMM, there are several of these row and column control lines that are brought out to the pins of the SIMM, and therein lies a good portion of the issue at hand. To be specific, there are four row control lines, labeled RAS0, RAS1, RAS2 and RAS3, and four control lines labeled CAS0, CAS1, CAS2, and CAS3. On the 32 meg SIMM, each RAS line controls 4 megabytes that occupies 16 bits of the data bus, and for each 4 meg RAS-controlled section, two CAS lines control each half to allow 8 bit wide access. If that last sentence was confusing, here's a nice diagram (which might be even more confusing :)

SIMM functional block diagrams from Micron

The mp3 player board uses the four RAS lines to enable one of the four 16-bit wide sections. It always asserts all four CAS lines at the same time (I ran out of FPGA pins and the chips that didn't get RAS asserted will ignore it). Using address pins A0 to A10 (as shown in the diagram) twice (row and column), there are effectively 22 address bits sent to the SIMM. Two of the address bits from the processor (or DMA) determine which of the four RAS lines gets used, for a total of 24 address bits. That's 16 million, and because two bytes are transfered at once, it all adds up to 32 megs of usable space and works quite nicely.

Well, that's the way is was. Somewhere, somebody changed the way SIMMs were made, and many newer SIMMs are connected in a very different way than that diagram shown above. I don't have a similar diagram for the newer SIMM, because I haven't found any datasheets on these newer SIMMs and I didn't draw a diagram (special thanks to Micron, by the way, for that nice diagram and at least keeping their data sheets on line... without Micron I would never have been able to figure out how to do this project!)

The newer SIMM uses only RAS0, and RAS0 controlls all 32 bits (instead of just 16 like the older SIMM). RAS1, RAS2 and RAS3 are not connected to anything at all! Worse yet, it uses 13 address lines instead of 11, where all 13 lines are used during the row selection but only 10 are used to select the column. The other three lines do nothing during column selection, but they are needed for the row.

The sad truth is that the mp3 player board has 11 address lines, not 13 (there are no more pins available on the FPGA). It has 4 row select lines, and three of them are useless of this type of SIMM. There is only a single column select line that is connected to all four CAS signals, so when the player writes to the SIMM, it will actually be storing 16 bits of data into both the upper and lower 16 bits of the SIMM. Using only one RAS line, 11 bits during the row select and 10 bits during the column select, there's only 21 effective bits of address info, which gives 2 million 16-bit wide memory locations, or 4 megs. It's unfortunate that there's 32 megs of memory on there, but due to the board design and the SIMM's arrangesment, only 4 megs is usable. Of course, today the firmware incorrectly concludes that it can use 8 and then crashes, but at least that can be upgraded to check more carefully which parts of the 32 meg address spaces it can "see".

Frustrating, but I guess it's better to know what's going on and at least be able to do something rather than have the code end up completely incompatible with these SIMMs. There appear to be many other arrangements on the newer SIMMs. For example, if this board were populated with KMC48C8100 chips (instead of KMC48C8000), it would still be a 32 meg SIMM, but 8 megs would be usable instead of 4 megs. On a simm like this, it possible to disconnect the RAS pin from two of the chips and connect them to RAS2 on the simm's edge to double the amount of memory the player can use, but there's nothing that can be done about the extra row address lines.

If you're shopping for a 32 meg SIMM to use with this board, be sure to look for the older style, which almost always has 16 or 18 chips (8 or 9 per side), where each chip has 24 pins in four groups of six. The older 8 meg SIMM look similar, but the chips are 20 pins in four groups of five.

June 26, 2001: I just posted a new firmware rev... the first one made within CVS. There's new DRAM controller in 0.6.3.2 that might cure the problems that recent firmware has had on the rev A circuit boards. More comments about what's changed are on the firmware page.

June 25, 2001: CVS is finally set up. It looks like it's working pretty well. The commands you'll need to access it are on the firmware page.

Tom committed file_uncache to CVS !! Tonight I commited some code that Zach sent in an email. Zach's code is a first attempt at reading in the subdirectories and files within them. It just reads the directory and prints them, but it does manage to recurse into each of the subdirectories.

June 24, 2001: If you haven't been following the yahoo group, it's looking like 0.6.3.0 is much more stable than the 0.6.2.x revs. I've spent an unbelievable number of hours chasing after this bug, probably more than I spent writing most of the code, and now that it's fixed I'll be able to work on adding cool features (or adding low-level support for others to add cool features). There's still a couple lock-ups that can occur, mainly if the IDE drive doesn't respond (need to add retries). Still, the 0.6.3.x firmware is much more stable, so if you've got 0.6.2.x on your board, it's probably a good idea to upgrade.

Today I fixed a problem with the makefile, and I changed the build process a bit to eliminate the binary files. Those changes are really to prepare for a transition to using CVS, probably within the next few days. The changes really only effect developers, who should grab 0.6.3.1. If you installed 0.6.3.0 from the image file (not source), there's no need to upgrade if you're not hacking on the code.

Also, I heard from Tom today and he's getting close to having file_uncache written. That's a really big deal, because this function is the key missing piece to being able to do some much-needed features, like playing files larger than the SIMM and keeping the first 50-100k of several files cached so that the next/previous buttons respond rapidly without waiting for the drive to spin up. This is very exciting news.

June 23, 2001: Ian did quite a bit more work on the navigation for the user interface. It's only partially written, but you can really see where it's headed. I did some more work with the DRAM controller and the new version seems to improve the stability, but it's still not perfect. On a whim, I up'd the rev number to 0.6.3.0. I've been working a bit with CVS and reading Karl Fogel's CVS book to make sure I really understand it. I'm hoping to move the development to CVS in about 1 week.

June 21, 2001: Yesterday I made some additions to the display code, and today Ian began the process of converting to the new display scheme. There's a couple new revs on the firmware page.

June 19, 2001: I did more hacking on the DRAM controller and finally put in that better bus arbitrator I've been planning for a long time. I actually did much of it over the weekend, and a miracle happened this evening... it worked perfectly on the very first try! It allows the DMA to get a lot more access to the DRAM than before, and it still provides a rapid response to the 8051 bus cycles by locking out any new DMA operations for 31 cycles after the 8051's PSEN fetches an opcode that could be a MOVX (access to DRAM).

The new rev (0.6.2.E) also includes Ian's latest code which uses the upper right button to select which parameter to edit, and all are edited with the INC/DEC buttons (which frees the arrow button for upcoming navigation features). Andy sent a small patch to one of the utilities that allows it to work under windows (using cgywin), so there may be a day when development can occur on Microsoft systems.

June 17, 2001: Ian did some really cool coding for the display to make a scrolling filename and a nice "slider" display of the volume setting. I just merged Ian's changes into the firmware (new rev on the firmware page). I also added low level support for the tone controls and timers.

June 13, 2001: I spent another long session working on cleaning up the remaining stability problems in 0.6.2.x, and there's yet another new rev on the firmware download page. I added a timeout check inside the serial port transmit routine. If for some reason the serial port output ends up in an infinite loop waiting for space in the output buffer, it will automatically reset the port and clear the buffer. This was one of the last places where an infinite loop could occur.

The other change involved hacking on the DRAM controller. Before I get into the details, I should mention that this "circuitry" is all soft configured inside the FPGA chip, so all you need to do is install the new firmware and your board will get this new circuitry. There are no changes to the physical hardware. These changes will work on all existing boards, either rev A or rev B.

The crashes seem so random that I've been worried that perhaps there may be a slight timing problem inside the DRAM controller. There are four things that compete for access to the SIMM. These are the 8051, the two DMA channels, and the DRAM refresh timer. The IDE interface shares resources with the SIMM (mostly due to using the hobbist-friendly 84 pin PLCC package chip instead of the less-expensive 144 pin TQFP fine pitch surface mount version). However, it works out that the IDE interface can use the same bus arbitration as the DRAM because its use is only from two sources, the 8051 and the IDE->SIMM DMA channel. So, I was worried that perhaps a 8051 bus timing problem may sometimes occur if the DRAM was previously in use by one of the other sources and the access made on behalf of the 8051 starts later than normal. This is really a long-shot, but I've been over just about every other part of the project a dozen times, so why not fiddle with the FPGA too!

I ended up designing a very paranoid circuit that watches the 8051 bus as it fetches instructions from the flash rom. There are six bytes that are the opcodes for the MOVX instruction, which is the only 8051 instruction that can access DRAM. The current firmware only uses two of the six opcode (@DPTR, but not @R0 and @R1). Still, I made the circuit generate a pulse just after PSEN latches a fetch of any of these six bytes. This pulse resets a count-up-and-hold counter for 32 cycles. When this little counter is at any state other than the hold (31 cycles following the PSEN-driven fetch of any of those six bytes), the bus arbitrator locks out any DMA or refresh access. This makes it absolutely certain that the control state machine will be in the idle state when the 8051 asserts either its RD or WR pins, which means that the DRAM access sequence will always begin with the exact same timing relative to the falling edge that starts a read or write. Of course, the opcode fetch may have been an operand instead of an opcode (or the MOVX address accesses a register in the FPGA and not the SIMM), in which case access to the SIMM is locked out needlessly for 31 cycles. Fortunately, that doesn't happen much and the performance hit is very slight.

I did quite a bit of work measuring the timing relationships of the 8051 and DRAM signals with my Tek 475 oscilloscope (with BTW, Robin picked up for me on E-Bay for Xmas :) The normal timing put the CAS pulse in the middle of the 8051's RD, so the data is certainly being delivered to the 8051 with plenty of timing margin in the normal case. With this new DMA lock-out circuit, that case is certain to happen every single time, as no other access can begin for 31 cycles after the opcode fetch that preceeds the 8051 asserting RD or WR. I have no idea if this has actually lead to any of the instability of the firmware, but it's in 0.6.2.C, and my board has been running for about 7 hours without a lock-up since I made this change (and the timeout in the serial port transmit wait loop). The previous revs also ran for hours in initial testing, so it's still too early to know if either of these changes really fixes the lockups.

June 10, 2001: Today I put quite a bit of time into trying to fix the last bug or two in 0.6.2.A. I played with the DRAM controller quite a bit, and there's a new rev on the firmware page. I haven't had it lock up in many hours of testing, but it's still too early to know if it's really stable.

I also did some preliminary work on a nice malloc and some groundwork for eventually having subdirectory/playlist support. There's some discussion about it on the yahoo group. 0.6.2.B has two new files, malloc.c and playlist.c, which aren't used by the rest of the project at all, but they are sort-of some planning for how things will eventually be done to provide playlists.

If you've been waiting for the laptop drive standoff set, it's finally an orderable part now. There's a photo on the page showing exactly how it mounts the drive to the circuit board.

June 9, 2001: I've been working on the firmware this morning and afternoon, and there's yet another rev on the firmware page. This rev adds storage of the volume and random play state into non volatile memory. Several bugs are fixed, but there's still one or two left causing infrequent crashes. I want to get this set of features stable before going after really complex features like subdirectories/playlists, sophisticated LCD navigation, etc.

Robin and I are working this weekend to get more of the beta test LCD boards built. If you're one of the few people who didn't get one, we're working on them and they should ship on Monday, June 11. Here's the page for ordering the beta test display. We've also got those standoffs that are the right size to fit most laptop drives. We should have a page to actually order them, sometime later this weekend.

During these last few weeks of working on the display board and related firmware, I've fallen pretty far behind on answering emails. I did a couple long sessions in the last couple days. If you have a really urgent need, please put "URGENT" at the beginning of your subject line.

June 7, 2001: After a long night of debugging, many of the bugs in the C version are fixed and it's much more stable. I added back support for all of the 6 pushbuttons on the board, and most of the other things that were in 0.6.2. I want to get to a stable version that does everything 0.6.2.1 does, and also stores the random seed and file position in non-volatile memory. I really want to have a stable version before making major changes for things like playing files larger than the SIMM, reading subdirectories, menus on the LCD, etc.

June 3, 2001: Robin and I spent quite a bit of time this weekend building those beta-test pushbutton boards. Robin soldered most of the pushbuttons! We had more adventerous souls wanting beta test boards than I originally anticipated. It looks like we'll have some extra boards after Monday, but we'll have to make a few more of the ribbon cables for them sometime during the week.

Tonight I put quite a bit of work into the firmware, and a new rev is on the firmware page. It adds a new serial input parser that's mostly converted to C. I originally tried to put the parser into the interrupt routine, but it was quite a bit of code and CPU time and somewhere there was a bug or two I couldn't seem to fix. Ultimately I went with the conventional approach of buffering the raw input and putting the parser into the main program (in C) and that's working quite well. Three of the new pushbuttons are supported, but it will be a lot easier to add support for the others now that the parser and interrupt driven serial I/O are working together well.

May 31, 2001: We finally have some beta test display boards ready to ship. Here is the page to order a beta display. At the moment there's just a few, but I'll build up some more this weekend. As you can see, the pushbutton board is hand-built and it takes some time. The display board has its own firmware, which is separate from the mp3 player firmware and is installed in a chip on the back of the display. The display firmware can only be upgraded by pulling and reprogramming or replacing the firmware chip. It is not downloadable like the mp3 player's firmware. The main motivation for this beta test is because the display's firmware isn't easily upgradable. If any bugs do turn up in the firmware, we'll provide replacement chips for $6 each for anyone who doesn't have an EPROM programmer (that can accept 32 pin PLCC chips). At the moment the mp3 player firmware only prints the filename as it starts playing, but it's easy to work with the display using printf, so more interesting support for the display in the mp3 player's firmware should not be too difficult.

May 27, 2001: I added support to the display board for its 12 pushbuttons. There are still a couple minor known bugs to fix on the display board, but they're easy to fix, so it's quite likely we'll be shipping beta test boards next week. I'll post an update when the beta-test display is an orderable part.

I did quite a bit of debugging on the player's firmware. I also switched the serial driver to use interrupts, and started the timer drivers (still not working yet).

Monday is a holiday, and I'm planning to spend most of the day on this project, so there'll be another update here on Monday night.

The yahoo group is working out quite well (thanks Russ), so if you're not on the group yet, it's probably a good way to get involved in the project or at least keep up with what's going on.

May 20, 2001: I hacked on the code all weekend, and I finally fixed the bug that was keeping the player from playing more than just the first file. I also did quite a bit of work on the display, and at long last it's (mostly) working. There is only minimal support for the display in the player's firmware at this point, but here's a photo of what it's doing today:

MP3 Player With Display Showing Filename Of Currently Playing File

The display board actually has an 8051-based system on the back side, and the firmware that runs on the display board may be found in the 0.6.2.5 source code. When you build the code, the makefile will create "lcd.hex", which is the code that runs on the display board itself. "lcd.hex" is about 95% complete. Unfortunately, the JW-002 doesn't support flash upgrading, so you need to use an EPROM burner to program the display's firmware. The boards we'll sell (hopefully very soon) will have the firmware already installed, but to upgrade will mean a chip swap. "lcd.hex" only needs to have debounce and reporting code for those 12 pushbuttons added inside a timer interrupt routine. So far it's working pretty well, as you can see I just got the bugs worked out of the C to asm (drivers) interface, so the player's "main.c" able to do what the assembly code was able to do before.

Using the display from the firmware is easy, now that the C-based firmware has the printf() function. It's just a matter of calling printf with the a couple display control bytes and the message to show. Inside 0.6.2.5's main.c, on line 202 is the printf that printed that filename on the display.

At this point, the larger picture is still a bit more work to do on the drivers to fill in missing functions needed for really cool features (timers, file_uncache, buffered serial I/O), and just a bit more work on the display's code to allow those 12 pushbuttons to cause messages to be sent to the player.

If you've been considering hacking on the project, but waiting for it to convert to C, now's the time to grab 0.6.2.5 and take a peek. You'll also need the very latest version of SDCC from CVS, as Johan fixed a bug just yesterday that allows SDCC to compile part of the code, and earlier in the week a critical (for using the display) bug in SDCC's string handling was also fixed. AS31 is also required, and the setup of all this stuff is easiest on a linux system (if anyone gets it to build under windows, please contact me with details). Not all of the system calls needed for really cool features are available yet (particularily file_uncache and timers), but they will be soon. The C code is now stable enough to try for some fairly complex features.

The next thing I'm going to work on is getting the last bit of code onto the display board, so that the 12 pushbuttons will be able to send commands to the player.

May 9, 2001: I fixed more bugs in the conversion to C, and now the firmware can actually play the first file! Of course, problems occur on the second one, but still it's pretty exciting to get the C version to start working.

I should write a bit about the display. The basic news is that I'm embarrasingly behind schedule. As you can see from the photo of exactly one month ago, the hardware is more-or-less ready to go, but as always, there's more work to be done firmware-wise. There's actually two firmwares. There is the firmware that runs on the display board itself, which isn't easily upgradable. That firmware basically implments the communication protocol to receive commands from the mp3 player, like "move the cursor to this position" or "print this string". Except for getting the change of state on the pushbuttons into the protocol, the firmware for the display board is complete. What's so far behind schedule is getting the firmware for the mp3 player itself to send useful commands to the display board. Most of this code will ultimately be written in C, so it seemed like such a waste to write a bunch of that code in assembly and then discard it in the upcoming conversion to C. If you look compare 0.6.2 to 0.6.2.4, the first 870 lines of assembly in "player.asm" were removed and re-written as about 260 lines of C code in "main.c" and 50 lines in "startup.c". While it does delay the project, this conversion to C really is needed to be able to handle a more complex user interface. I'm pretty good with assembly, but not that good!

Russ created a message board at Yahoo Groups, dedicated for this project. If you're interested in chatting with other users, give it a try. Please don't fill the message board up with questions like "when will xxxxx be ready?"

May 6, 2001: I've spent almost all weekend playing with SDCC and converting the main program portion of the code from assembly to C. That's the easy part, really. The hard part is creating function prototypes for all the existing code that's going to remain in assembly, and making the "glue" code that allows the existing assembly code to be called from the C program. Some other ugly issues I've been putting off, like properly responding to interrupts with the banked code memory also had to be addressed. So far I've got fifty functions defined to tie the existing drivers and filesystem code to the C application, and most of them actually work. At this point, I've got the C application more or less written (functionally the same as 0.6.2.1), and it sort-of works after much debugging. Saddly, there's only so many hours in a day. In the spirit of ESR's "release early, release often", I put the code in its present state on the firmware page. I only posted the source, not a ready-to-use image file, because it really doesn't run just yet. Still, if you've been following this project and want to get your hands dirty (but not assembly-language dirty), take a peek at the C code. It's all in "main.c" right now, and it's only a few hundred lines of code to read (a lot easier than trying to make sense out of more than 9000 lines of assembly!!)

May 3, 2001: This evening I finally put Tom's parameter storage code to use (after some edits to it). Version 0.6.2.1 stores the volume setting as a non-volatile parameter. It should be easy to add more settings to the non-volatile storage, like the file that was last played and the random number "seed", but at the moment only the volume setting is stored.

May 2, 2001: I just put version 0.6.2 on the firmware page. Version 0.6.1.E has turned out to be quite stable, so I'm planning to call 0.6.2 "stable", unless I hear reports of significant problems in the next several days. The main change in 0.6.2 is proper support for using the board without a SIMM.

Apr 22, 2001: Quite a lot has happened since my last update two weeks ago. We finally have more assembled boards in stock. They are "Rev B" boards, with a minor change in the power supply. The change makes the input range of the 2-pin connector 6 to 10 volts, instead of 4.5 to 6 volts. The advantage is that the power supply isn't easily damaged to applying too much voltage (say 12 volts to the 2-pin connector), and the TIP102 transistor doesn't run nearly as hot when the board is powered with 14-15 volts on the 12 volt input. For battery operation, six AA cells are needed with the Rev B board, instead of just four.

I'm behind schedule with the display board beta test. I had wanted to send out beta test boards two weeks ago, but a week of travel and meetings put me a week behind with Veris (the day job, this MP3 player is in my off hours), so I didn't manage to do much with the MP3 player project in the last couple weeks. It's looking really good that it's actually happen this week. Also planned for the near future is a page with much more detailed info about the display board. It's always risky to make promises, but at the very least I will be working on this project this week and this page ought to get a couple updates through the week.

A group of students at BYU did some work to try to add ATAPI device support to the firmware. They wrote these seven web pages about their project. The work is incomplete, but it looks like they did have some success implementing some of the low-level code. I know of one other person who's interested to try and implement support for ATAPI devices. Eventually this code could lead to support for CDROMs. For now, I'm going to stay focused on getting the display board working and on display and navigation features in the firmware. When the display stuff is mature, I'll probably look into this ATAPI/CDROM support, but I will of course accept patched in the meantime :)

I also managed to get a USB Adaptor Board recently (from www.in-system.com, who has been acquired by Cypress Semiconductor and their old website has vanished) It's quite a bit smaller than the one shown in that photo. It's about 2.5 by 1.5 inches (6.4 by 3.8 cm), with the USB connector on the opposite side of the board. I haven't had time to do any testing with it, but it looks like it ought to be possible to get it to work with the player. The trick is to have it tell the player when the USB is active and have the player not attempt to talk with the drive. These boards are about $42 in single piece quantity, which is a bit more expensive than I'd like, but maybe that's ok?

Apr 9, 2001: This weekend I made display adaptor board layout and etched three prototype boards. Here's a photo of one of the boards with a new display (still has the blue protective coving):

beta test display board

I actually wanted to be at this point on Saturday, as the firmware still needs a bit of work. I wanted to ship four beta test boards on Monday... it's really close, as you can see from the photo, but just a bit more work is needed in the code that goes in the chip on the back of the display board.

The bad news is that it's not looking too good for getting much done on this project through the week. Tuesday is dinner I need to go to, and I'm flying out on Wednesday afternoon to visit a (Veris) customer on Thursday. It may next weekend when I can finally ship the beta test boards out. I made three tonight, and I'll probably make 3 more, and so far I've heard from 4 people who want to give these boards and the first firmware a try. Of course, we'll have some nicer "professional" boards made in a couple weeks, with the usual green solder mask, silk screen, and plate-through holes.

It's looking like we're going to sell a kit with all the items shown in this photo, for $47. That's the display board itself, with a firmware chip installed that has the firmware needed, the 17 pin ribbon cable (attached to the board's connector), the adaptor circuit board with 12 pushbuttons, and the 4 pin cable to connect to the mp3 player. It's also possible to buy the display board from Earth Computer Technologies ($39), if you want to program an EPROM with the firmware and build your own adaptor board and cables. Soon I'll add a page with quite a bit more info about the display, including the firmware source code needed to make it work.

Apr 3, 2001: Here's a little image I drew that shows approximately what I'm planning for the display adaptor board. The scale is 100 dpi, so the planned board size is 5.5 by 1 inch (14 by 2.5 cm).

circuit board drawing

On the right side is a ribbon cable connector that will connect to the display board itself, and a 4 pin molex header that is a right-angle version of the one on the right side of the mp3 player. The design allows for 12 pushbuttons. The exact function of each pushbutton will be determined by the mp3 player's firmware, not the hard-to-upgrade firmware of the display board. Though not shown in the diagram, there ought to be space to put 12 pairs of holes so allow off-board pushbuttons to be easily connected.

At this point, the big question is how to arrange the pushbuttons on the board? This drawing shows one possible scenario. I added the green text to illustrate some potential functions for the buttons, but keep in mind that the exact functionality of each button is due to firmware in the player, not the design of this board (which is what I'll be concentrating on this week). If you have any opinions or insights about how these buttons might be well arranged, now would be a really good time to email, but please please please, try not to get caught up in all sorts of complex details about menu systems, playlists, etc. All that sort of stuff is to come in the mp3 player firmware, but after this board is finished.

Apr 2, 2001: This weekend Robin and I built up a few mp3 player boards from the extra parts we had. So the good news is that everyone who was waiting for a board (with a valid order) is getting a board shipped today. At the moment, we have just two boards left, and a small handful of invalid orders (shipping cost confirm req'd and not received, declined credit card, check/money order not received, etc). We also built up more of the 8051 boards, which means we're not in danger of running out of those and getting into this time-consuming business of trying to be fair about who gets the last few boards. (we should have plenty more mp3 player boards in about 2 ½ weeks).

On LCD display board front, I've been having trouble actually getting a good number of them. On Friday I was told that a box of them is being shipped, so hopefully we'll have some to offer soon. We're planning to sell the display board a little kit, which will include the display circuit board with a ribbon cable attached, and a firmware chip installed to implement the command set. The kit will also include a little adaptor board that has 12 pushbuttons, a connector for the ribbon cable, and a 4 pin connector that's the same as the one on the right side of the board. Of course, we'll include a short 4 pin cable to connect between the boards. The adaptor board is simple, it's just one MAX232 chip and some capacitors and the pushbuttons. The MAX232 converts the serial signals, and provides a negative voltage which is needed for the LCD display. That little slide adjust on the top of the display allows the contrast to be changed, and the negative voltage from the MAX232 is enough for the right most setting to be really dark. I don't have all the costs added up just yet, but unless it means losing money, I really want to sell this display kit for under $50. It will also be possible to buy the display board itself, without the firmware installed and without the adaptor board and cables, directly from the vendor (qty=1). I'll post a page with more info about this, including the firmware source code and instructions to do-it-yourself, probably next weekend (if I actually receive the package this week). The display board I currently have, shown in the photo on March 7, has many mods on the back side for firmware development and other hacking, so it isn't a good example for testing and explaining what we'll actually be able to sell. My short term plan is to build up a few kits with "beta test" firmware, for a few adventerous souls who'd like to try the display right away (I have 4 people on my list so far, email if you're interested). Unfortunately, the display board isn't easily firmware upgradble. The firmware is in a PLCC socket and requires swapping the chip. It isn't downloadable like the mp3 player board. I have the firmware more-or-less finished (still a bit to do with the pushbuttons), but it's always possible that there's a bug or two, so I want anyone who buys one of these boards early-on to understand that they may need to pull the chip and reprogram it (we'll use flash on the first boards), or get a new chip if an eprom programmer with PLCC socket isn't readily available. In the long run, my plan is to keep the display board firmware simple and avoid adding features to it, and instead add fancy features into the easily upgraded mp3 player firmware.

On the firmware front, I haven't heard any complaints about the out-of-memory bug with 0.6.1.E. I ran it for quite a while and I've been seeing some warnings from the memory allocation routines, which may not be a big deal as nothing bad seems to be happening. I'm starting to think that some of the problems I was seeing may have been due to damage to my board's power supply (that board with the yellow dot has seen a lot of abuse thoughout this project, which is why it has a yellow dot... so we don't ever accidentally mistake it for a new board that we would sell). There obviously is a need to do a bit of clean up in the code before a 0.6.2 release. As you can tell from reading this page, I haven't had much time to do much with the firmware in the last couple weeks. It looks like we've done just about everything we can do with getting more boards built and be fair and satisfy everyone who's been waiting, so hopefully I'll be able to get some real work done on the firmware and LCD board in the next week or two.

The Rev B circuit board will have some minor changes in the power supply, which result in the lower voltage input connector having a range of 6 to 10 volts. A couple of people have been unhappy hearing about this change, so maybe it's worth taking a moment (in this already too-long update) to explain the change and the motivation behind it. It was my hope that the change would provide a 4.5 to 10 volt input range, but that didn't really work out. The new circuit will actually run a bit lower than 6 volts, but not near 5 volts. The biggest advantage of the change is that the low voltage input isn't easily damaged if you apply 12 volts. I had a couple people return boards with the 74AC14 chip blown, which was almost certainly due to applying a higher voltage to that input. The 74AC14 has an absolute maximum of 7 volts (though they will sometimes survive more... sometimes). In some cases, the 74AC14 will blow in a way that allows the supply to temporarily output too much voltage, which causes the FPGA or STA013 to also fail. The new mosfet driver chip can handle 14 volts. The 10 volt limit is due to the capacitors, though they can usually take a bit more voltage without trouble. Making the board more sturdy to abuse was a big concern for me. The other advantage of the higher voltage input range is that the linear step-down preregulator (TIP102 transistor) will have less voltage across it. When the board powers a laptop drive, this TIP102 part runs hot. It's still within its spec, but it can get very hot to the touch, particularily with a laptop drive that draws a bit more current. The original idea was that the hard drive would never spin for any long period of time thus limiting the temperature rise... but has you can see from the history of these updates, that has turned out to be easier said than done, with the 0.6.x firmware still not completely debugged enough to be called "stable" (though 0.6.1.E is pretty good).

As far as motivation behind the design, the linear preregulator was done for two reasons... originally to allow a power supply I first designed for batteries to run from 12 volts, and to provide protection from the 60 volt spikes that will happen in a car if the car's battery is disconnected while the engine is running (I didn't want to have a fuse that blows). I originally wanted to run from four NiCd cells. It's looking like the 0.6.x firmware can run for 5-6 hours from four 1500 mAH NiMH batteries (available from Radio Shack), using the 0.6.x firmware and 16 meg simm... which is quite a bit better than Creative Lab's Nomad Jukebox! This new design will need six cells instead of four. I know that's a bit heavier and bulkier, but since the board is 5.75 by 4 inches (14.6 by 10 cm) due to using through hole components that hobbists can easily solder, the extra two batteries don't seem so bad, and the play time will be longer. The larger voltage range also means that alkaline batteries may have a chance, though NiCd or NiMH are much better at suppling the large current needed to start the laptop drive motor.

For the distant future, one interesting idea I've heard is to actually build two separate 5 volt supplies, one for the drive and one for the board. This would be a major redesign, but the idea is interesting because then each supply could be designed and optimized for just its expected load range, instead of the current (difficult) design which needs to handle such a large range of load currents, and the supply dedicated to the drive could be completely shut off. I'm intrigued by this because it turns out that laptop drives draw a significant current even when in full sleep mode. My Hitachi DK23AA-12 drive measures 17 mA in full sleep. If anyone out there reading this is a switching power supply guru, I'd be interested to hear from you, particularily about how to get 5 volts at 1.2 amps from a 4 to 15 volt input (SEPIC, perhaps? ... currently using flyback). Well, for now I think the Rev B board will be a minor improvement, and if you really wanted to run with a 4.5 to 6 volt input, well, I'm sorry (though we have two assembled boards and a several kits left as of today).

Mar 28, 2001: It's been a while since I updated this page. We ran out of the assembled mp3 player boards. I've been spending most of my project time working on getting the next batch of boards ready. I did end up making a minor change to the power supply, which turns the low voltage input range from 6 to 10 volts, instead of 4.5 to 6 volts. It's looking like we'll have the new bare boards next Tuesday, and then it's a two week process to get the boards assembled (it can be done faster, but the cost goes up sharply). This last week has been a not-so-fun job of counting all the parts and ordering the ones we're missing, which really isn't very interesting, but I thought I'd put an update on this page anyway. The processing of orders is usually pretty simple, but it gets complicated when we're almost out of stock. We also happened to run out of the 8051 development boards at about the same time, doubling the number of orders that need special attention, but those are fortunately back in stock again. Robin has been out of town most of this week, and I'm not nearly as good at it as she is (and I don't end up getting much done on the firmware). Well, with a bit of luck the last pending orders will be completed or canceled and we'll offer the boards to others who are waiting, and the board assembly will go smoothly over the next two weeks.

Mar 19, 2001: I spent quite a bit of time playing around with tweaks to the power supply. Today the 2-pin connector on the right side of the board accepts 4.5 to 6 volts. I really wanted to widen the range to 4.5 to 10 volts (for Rev B boards), but it's looking like I managed to make it about 6 to 10 volts. I'm not so happy about not being able to run from 5 volts, which is such a common regulated power supply as well as 4 NiCd batteries. I'll probably do a bit more fiddling. Maybe 6 to 10 volts is ok?

I received a bug report about as31, though it was the S-Record output format, so it doesn't effect this project which is based on Intel-Hex format. I did fix an annoying problem where the command line version wasn't returning error codes to the shell, which causes "make" to continue building when it should stop. If you're building the project from the source, be sure to grab this new version of the AS31 Assembler.

Mar 18, 2001: I spent yesterday and this morning working on the display firmware. Most of the features described on the LCD protocol page are working now. I added more details to that page as I wrote the code for each part. This morning I got the scrolling to work. I also built a little prototype board with 12 pushbuttons. The display board firmware reads the buttons (3x4 matrix, 7 I/O lines), but a bit more work is needed for up/down detect, auto-repeat, and support in the protocol. I'm not sure exactly what functions will ultimately get programmed to the buttons, but the display board adaptor will be able to provide 12 buttons. I suppose 4 want to be for 2-dimentional cursor/selection movement and 1 for enter. The existing 6 buttons probably want to be duplicated, except random mode may turn into a menu choice. Right now the big question isn't exactly what to do with each button, but how to arrange them on the board that will fit just below the display. The 4 buttons for up/down/left/right probably want to be in a diamond shape. I'm imaging that this board will probably be about 1 inch high by 5 inches wide (2.5 by 10 cm), and a portion on the right side will be taken up by connectors and 1 chip.

We're nearly out of boards. I've been putting off ordering more circuit boards, because I wanted to make some minor changes to the power supply on the next round of boards. The main change I've wanted to make is to replace the 74AC14 with a proper mosfet driver chip. I spent the afternoon tweaking a TPS2814 chip onto a board. That's the easy part... the hard part is that two of the inverters from the 74AC14 form a software shut-off circuit. The idea is that the firmware can turn off the power supply (the play button wakes the power supply up). I've never really done much to support this from the firmware. There's very little extra space left on the board and many attempts to build another shutdown circuit were not successful, so maybe I'll just leave the board as it was, with the 74AC14, or maybe I'll change to the TPS2814 and abandon the shutdown circuit. I did some playing with a LMC7211 comparator to make a shutdown circuit, and it's looking like it just might work. It's a SOT-23-5 surface mount package, and I've tried to avoid surface mount to keep the board easy to assemble from the kit. Everything's a trade-off, I guess, but these really are pretty minor tweaks to the power supply. Well, one way or another, I really need to order boards on Monday or Tuesday, so I'll have to make a choice and go with it for the next batch of boards.

Mar 16, 2001: I'm going to try releasing beta test firmware very frequently, starting right now. I just put 0.6.1.E on the firmware download page. This version fixes the no-sound bug. There is still one major bug left, which I'm calling the out-of-memory bug. Eventually, something goes wrong in the memory manager and usually this results in a significant memory leak, which you'll see in those message about how much memory is available after each file is finished playing. In some rare cases, memory pages will get mis-managed in some way the triggers one of a few sanity checks that will abort the player and produce a very long dump of critical memory areas. If you're watching with a terminal and happen to capture one of these giant memory dumps, please email it to me.

My hope is that releasing beta test firmware frequently will allow you to keep up with changes in the project and try out the very latest code, if that interests you. I could also use more feedback out how they're working, but please keep in mind that a bug report is much more valuable if you can reproduce it with the debug messages turned on and capture them to a text file attached to your email (type "DEBUG", or edit the code and uncomment "setb debug"). The only potential downside is that our little site has limited bandwidth and quite a number of people run those abusive archiver programs (Teleport Pro, WebZIP, etc). If this gets to be a bandwidth problem, I'll probably start removing older beta versions that aren't of much interest.

Mar 15, 2001: It's looking like I may have finally solved the no-sound problem that happens with some boards. It turns out that the STA013 MP3 decoder chip requires a bit of time to initialize itself after a reset. The tricky part is that there is a code burried deep within the config file provided by the manufacturer (ST) that does a soft-reboot. They don't document this anywhere, and it's not mentioned in the suggested algorithm for sending the config data. I added a 0.6 ms delay into the downloading just after any writes to register address 16 (the soft reboot register), and this has completely fixed the no-sound problems on the board I have that reproduces this problem regularily. I emailed firmware images to the four people who've reported this problem recently, so hopefully I'll get some feedback about how this change effects their boards. If you have a board that sometimes boots up and produces no sound but says it's working, please contact me and I'll email you this firmware file. Feedback is really valuable with these hard-to-reproduce problems. Hopefully this no-sound issue will finally be fixed.

Mar 14, 2001: Once more, I've fallen a bit behind on updating this page. I did quite a bit more work on the display firmware and fonts. I create this page with the LCD's fonts and another page with the planned communication protocol for the display. I still need to write quite a bit of the code for the protocol. That's probably happen this weekend. I'm hoping to have a good idea of pricing for these display boards by next week. I'm planning to have some small adaptor boards and cables to allow it to easily plug into the MP3 player and also provide remotely mounted pushbuttons. It'll take a couple weeks to get these boards and custom cables ready. If you're impatient and want to get a display as soon as the firmware is ready (and build your own cables and adaptor board), contact me by email.

Recently I've been putting quite a bit of work into solving the no-sound bug that happens with a small number of the boards. Some times the MP3 decoder chip doesn't get properly initialized, or at least that seems to be what's happening. Most boards only very rarely have this problem, if at all, but a few boards do it much more regularily. Last night I finally managed to write some code that can reliably detect when the chip isn't properly initialized and it retries. Each retry takes about 2.5 seconds, and it seems to eventually get the chip initialized properly. I'm not happy with such a kludge, so I'm still working to try and find out exactly what causes the improper initialization, but at least this retrying allows boards to work properly. If you have a board that does this no-sound problem, please email me and I'll send you the latest beta-test code.

Mar 7, 2001: I haven't posted here in a few days. Last Thursday I got a LCD display, which looks like a good choice for this project. It's 8 lines by 24 characters and includes an 8051 based system on the back side, so very little extra hardware will be needed to make it work. It's new (unused) from a surplus supply vendor, and it came without working firmware or any significant docs. They've got a very reasonable price on them, considering that it's got a complete 8051 system on the board and the display area is large, about 4 inches wide by 2 inches tall (5 by 10 cm). That's just the active area of the display, the board itself it only slightly smaller than the MP3 player board. Here's a photo:

LCD display on a circuit board

Feb 28, 2001: Fixed a bug where pressing the next or previous button while the file was still being read could cause file_close to be called before the IDE driver would finish processing all the queued read requests.

There still seems to be another "no sound" bug, different than the one that I fixed on Feb 21. There's also some sort of memory management problem that shows up mysteriously after many tracks are played. Both of these aren't very easily reproduced (yet). I really want to get these last two known bugs fixed before a 0.6.2 release.

Feb 25, 2001: Yet another bug fixed. This time it was a problem in the way cached FAT sectors were being indexed. It only tended to happen with certain fragmented filesystems. Tom actually sent the debug messages that exposed the problem. From there, it took an hour to write code to artificially recreate the bug, and then only a few minutes to actually fix the offending code.

I'm still having some problems with the code... it may be that the fat32 code can't handle full concurrency with the IDE driver (which I enabled when I took out the workaround for the DMA bug). This problem is very hard to reproduce, so I'm currently running another lengthy test, and hopefully there'll be some useful info available tommorrow evening.

Our ISP's router is still pretty shakey. They think that the problems are fixed, but they're not. I set up a little script to do pings every minute and log the result, and it looks like we're having a 5-15 minute outage about once every hour. That's pretty bad, and they'll be getting a call in the morning with my logged data. If our little web site hasn't been responding for you, well, if they don't get the act together soon we'll move to a different ISP.

Feb 25, 2001: It looks like I finally figured out what was causing the occasional DMA errors (when not using the busy loop in 0.6.1). It was a small error in the FPGA config. Nothing an all-night debugging session (currently 4am) can't take care of.... Reading the drive is noticably faster with the busy loop gone. I really need to get some sleep. Later today I'll do quite a bit of testing.

Feb 24, 2001: I've been working on the firmware this afternoon. I just fixed a bug which would sometimes cause only the first several seconds of a file to be played. On the no-sound front, three people who's boards reproduce the no-sound problem have tried the code. Two reported the problem fixed and one "got better". If your board does this no-sound behavior when it cold boots with 0.6.x firmware, and you read this before 0.6.2 is released, please send me an email and I'll send you the work-in-progress firmware to try on your board.

It's becoming obvious that some problems are being caused by bad SIMMs. The SIMM detect code in 0.6.x only tries to detect the SIMM size, and it will properly detect even very bad SIMMs. Version 0.5.x will work with many very faulty SIMMs, because it only uses a tiny portion and only stores the data for a very short time. Now that 0.6.x is making a lot of use of the SIMM, it is sensitive to faluty SIMMs. Still, it's amazing how long it can take for a bad SIMM to finally cause a crash, as it appears that bad SIMMs usually are partially working. I only have a couple bad SIMMs, so if you happen to have any 72 pin SIMMs that are bad, I would really like to get them for testing. I really need to learn a bit more about testing DRAM and write a good memory tester into the firmware, so in the event of a bad SIMM, at least it could abort and run version 0.1.1 (which doesn't use the SIMM at all).

I also did some more shopping for a nice display. I want to have a relatively large graphical display, but I don't want it to end up costing a fortune.

Feb 21, 2001: Last night I reorganized how the STA013 MP3 decoder chip is initialized, which is might solve the bug where the player will sometimes start up and appear to be working normally (via the serial port), but no sounds is made. I sent a copy off to Patrick, who's board/system seems to be able to reproduce the problem (the 3 boards sitting on my desk almost never do it).

We've been having problems with our upstream ISP. They've been down for over 5 hours today! They claim they are replacing some hardware that is supposedly the cause of the recent outages. If their uptime doesn't improve soon, we'll probably switch to a new ISP. The company was sold several months ago, and the guy who ran all the technical aspects left 4 months ago, and since then their reliability has gone downhill. If you've been checking this page and the server hasn't responded, well, I'm sorry about that, but there's not much we can do when our upstream provider to the internet is off-line. Our linux-based server's uptime is 219 days today. I wish our ISP was that reliable.

Feb 18, 2001: Today I fixed several bugs in the code, including a really bad one in the memory manager initialization (which often resulted in the player reporting out of memory right as it started up). There's a bug where sometimes the player will start up with the audio muted, and a cold reboot usually fixes it. I took out the muting at startup, and so far I haven't seen this problem again. It's hard to tell if this is really fixed or I just got really luckly (powered the board off/on about 50 times) 0.6.1 also had several types of crashes involving the pushbuttons, mostly due to changing the program's state at the time of a button press, rather than waiting until a state where the change makes more sense. I added code to continue reading while paused (if the drive was spinning) which means the cache gets filled while paused and the drive shuts off as soon as possible. I also changed the drive wake-up to not do a hard reset if the drive wasn't in sleep mode, which makes rapidly pressing the next or previous buttons much more responsive. I added another call to free_fat_memory to avoid temporarily leaking some memory when the next/prev buttons are used. I also fixed a few places where interrupts weren't being disabled when they needed to be.

I updated the plan above, shooting for bug fixes only for 0.6.2, hopefully to finally have a stable firmware that does caching.

Feb 15, 2001: Bad news, 0.6.1 isn't looking nearly as stable as I had thought. Three people have reported lock-ups so far, so it looks like I'll have more work to do on it this weekend. I did a test run with 4 NiMH AA size batteries, and it played 112 files before the batteries dies! Unfortunately, the 0.6.1 doesn't handle a dead battery gracefully, as the board reboots when the drive is started. I need to add a check for lots of reboots in a row and do a proper shutdown. It's going on the to-do list for 0.6.2.

Feb 14, 2001: I just posted 0.6.1 to the firmware page. Tom sent a patch that fixes the pushbuttons, and I just took care of the memory leak from the FAT sectors. We both ran various incremental revs of this code for a couple days and it looks pretty good. There are a few known problems, which are mentioned on the firmware page. Please download and give 0.6.1 a try, and let me know if you see any problems. If no major problems turn up by the end of the weekend, I'll send a message to the announcment mail list. There's still a lot to do, but 0.6.1 is really a major milestone.

Feb 13, 2001: Last night and very early this morning I did some more work on the firmware. The audio glitch problem is some sort of a strange problem where DMA transfers are targeting the wrong place in memory, but it happens very infrequently, never happens (so far) if I add some code to just wait for the DMA to finish. The read performance hit isn't really bad, so I'll probably leave this in for 0.6.1, in the interest of getting a nice DRAM caching firmware rev posted that is actually usable.

Tom's long filename code is really nice. It's pretty cool seeing "10,000_manics_these_are_the_days.mp3", after having looked at "10_000~1.MP3" for so long! Tom also sent a patch today that adds much of the pushbutton support back in. I promptly broke some of it, doing an overhaul of how the low-level code handles the pushbuttons. The idea is to separate the detection of user actions (timing sensitive) from the main program which services them (without deterministic timing). The new code passes these events in a fifo, instead of fiddling with flags. The idea is to be able to convert the main application, which runs in a loop without any particular timing, to the SDCC C compiler. The low level functions, many of which are timing critical, will remain in assembly. Of course, all this other new code (caching FAT32, queued request IDE and playback, etc) are designed for a clean separation between the main application and the low level drivers. I want to get the application part converted to C as soon as reasonably possible.

Well, I could go on about the details, but the short story is that the code is really coming together and 0.6.1 is getting close, with caching, pushbutton support, and no significant delays reading data. I just reorganized the "What's Planned Next" section at the top of this page, to reflect what's currently planned for each upcoming firmware rev.

Feb 11, 2001: Today I spent the entire day, about 14 hours, working on the firmware, trying to get to 0.6.1. I wrote a new main loop which can begin playing a file while it's still being read from the drive. Getting things running concurrently exposed dozens of bugs that don't show up in 0.6.0. I wanted to get all the drivers converted to interrupts, but so far only the MP3 DMA to the decoder chip is interrupt driven. I've been battling little "glitches" in the audio output all night, due to various bugs and missing checks here and there. There's still some small problems, but it's getting much better.

The really exciting news is that the overall performance is really much better. Reading from the drive is just under 1 Mbyte/sec, and that's with the IDE driver still running without interrupts! Now that the MP3 transfer is interrupt driven and the play request queue is working, many seconds of data can be queued up.

Tom Parker sent two patches, which I still have to work with and include into 0.6.1. His first patch provides non-volatile parameter storage, which will be really nice for things like keeping the volume setting, starting up on the same track, and probably a lot more things when the display is available. Tom's other patch adds long filename support. Very cool. I really want to play with these, but I can't stay awake much longer (2:30 AM, been coding since 10 AM).

Feb 4, 2001: I started the new User Photo Gallery page today. Later today I'll start the technical documentation table of contents page, and then update the links at the top of all these MP3 player pages (not fun work) to point to those two new ones, so that all the new pages are easily reachable without having to read this recent news page.

Feb 3, 2001: Yesterday and today I did some of the work to convert the IDE driver to being interrupt driven. The "file_cache_work" function now uses the transfer pending status bit on each block, to avoid using a cached FAT sector group that hasn't been fully transfered yet. In 0.6.0 the IDE driver is run immediately after file_cache_work until is gets to the idle state, which makes things simpler and easy to test, but for good IDE performance the transfers really need to be able to happen concurrently with file_cache_work, as it can take quite a bit of CPU effort to prepare a cluster transfer, but once the cluster transfer is in the request queue, the IDE driver will (hopefully soon) be able to work on transfering that data while the FAT32 code does the work to prep more transfers. I could go on about other optimizations already in the code that are intended to work together with this, but that's old news...

I also added a little optimization to remember the last FAT sector group, so in the common case of low fragmentation the next cluster can be found much more quickly by avoiding the search for the correct FAT sector in the cache. This should make more CPU time available to the main program, in the long run. I added a bit of code to correcly mark which files depend on each FAT sector group, so that it'll be possible (not written yet) to free the unneeded FAT sectors in file_close. I wrote the free_fat_memory functions, though it's still untested. 0.6.0 leaks memory because it never frees FAT sectors, even after all the files that needed them are closed. I wrote a first attempt at the interrupt service routines... but they're not complete enough yet to try them.

I drew a schematic for the power supply. There's getting to be several of these technical documentation pages, and I'm planning many more. I really ought to edit the links at the top of all these pages and add a link to a table of contents page for the technical documention. Aside from this new schematic page, there's the STA013, library functions, and memory map. I'm also going to start a User Photo Gallery page soon (to be linked near the top of all the pages, probably between the FAQ and this Recent News page), where I'll post photos that I receive. If you'd like to share a photo of how you used the board, please email it to me and I'll post it.

Jan 31, 2001: Ok, it ran for a few hours, so what the hell. Version 0.6.0 is now available on the firmware download page. At the last moment, I added a bit of code to turn the verbose debug messages on/off by using the Vol+ and Vol- buttons. Even with the messages off, the read speed is approx 100 kbytes/sec. There's no attempt to begin reading the next file while the last one is still playing, so you'll wait about 40 seconds of silence if the next file is 4 megs. (much longer with debug messages turned on) This firmware release is mainly to get some code out to others who've been wanting to hack/contribute, and to give you a look at the new caching.

If you load this firmware, it's a bit difficult to get rid of it. Typing "QUIT" crashes (there is a mix of the new/old IDE drivers causing this if the drive is in shutdown, and the user interface isn't called properly while reading/caching). To get back back to the monitor, you'll need to cold boot, and press 'S' (as descibed on the upgrade page). There is only a 1/2 second wait for the 'S', though you can press it earlier in the boot process.

Please, there are many bugs left in this code, so if you do report a problem, make sure you've been capturing the verbose debug messages. If you want firmware that works nicely, this is not the rev for you... stay with 0.5.1 until more of the bugs are worked out, the main program uses the caching in a better way, and the IDE driver gets up to good performance. If you've been waiting to get your hands on the new FAT32 code to do some coding, now you can. Please let me know what you have in mind, so I can plan for it.

Jan 30, 2001: Tonight I fixed even more bugs and got a very simple main program going. It reads the file (very slowly due to the lots of verbose debug messages), shuts off the drive and plays it from the cache, then starts up the drive to read the next file. No pushbutton checking or other features... but it seems to be working pretty well (if the SIMM fills up, it only plays the part of the file it was able to read). It doesn't try to read from the drive while also playing. All those nice things will come, but this is the very first working player based on the new FAT32 code with caching. I'm going to let it run for several hours, and if it doesn't crash, I'll release this as 0.6.0, which is really only useful as a developer release, but I need to get some code in the hand of other folks who've been wanting to hack on the code.

It's not even midnight yet... (I've been up til about 3 am nearly every night for the last week working on this code.) I'm going to go rent a movie and have a couple beers!

Jan 28, 2001: Today I wrote the dir_read function, which uses file_read to grab the raw directory bytes. After fixing bugs in file_read, and debugging dir_read, I kept getting strange failures, but at random places in the directory. Well, after much investigation, it turns out that there was a timing bug in the dram controller. The timing problem occurs very infrequently and until I wrote the directory parser, there just wasn't a large enough number of accesses to the dram to really expose it. In fact, I finally had to replace all the movx instructions with a call to a little function that reads the memory 32 times and compares all 32 reads to see if they were the same. The problem would only show up 3-5 times out of many thousands of calls to this function! Well, after a few hours of FPGA hacking (not that long, considering that the Xilinx software is so slow and takes 15 minutes to recompile the FPGA, using a 800 MHz PC), I lengthened the time allowed for precharge after a refresh cycle, and that fixed the problem.

I really wanted to release a firmware rev tonight, but I really need to get some sleep. More or less all of the needed FAT32 functions are written and seem to be working (need to update the library page), and I have two little test programs, one that reads the first file into the cache (100 kbytes/sec) and then plays it with the drive off, and one that prints a list of all the files in the main directory. Tommorrow, I'll throw together a little main program that does the same features as 0.5.1 with the new FAT32 functions.

Jan 26, 2001: I just got about 1 second of playback from cached data!! Tonight I've fixed dozens of bugs and it's really exciting to hear a bit of sound, even if it is only 1 second and doesn't work every time. Still more bugs to fix, and the dir_read function has to get written, but hopefully I'll be able to salvage some code from 0.5.1 for that. It's really starting to come together now! Update (3:10am), I fixed more bugs in malloc_blocks, file_cache_work and file_read_block and it's now playing an entire 6.1 meg song from the cache! Polled/sync IDE driver read performance sucks (only about 100 kbytes/sec), need to work on that and write "dir_read" this weekend. Time to get some sleep...

Jan 25, 2001: Another late night coding session... wrote all the code which will read data after it's already in the cache (much easier than getting from the drive into the cache), and the new playback code, which now has a queue of blocks of MP3 data waiting to be played. I spent a couple hours updating the library functions page. It now has a status indication for each function, so you can see roughly how far along they are, and I finally got around to documenting the file access functions. This documentation stuff is time consuming and less fun that writing the code, but it'll let you know where things are at, and (hopefully this weekend) when an initial release of the code is out, if you want to hack on the program you'll at least have some documenation about what these functions are supposed to do.

The initial release will be built with a polling loop, that will run the IDE and play drivers by polling. These are meant to be interrupt driven, which will give much better performance to the IDE driver. I want to release something as soon as possible (working), even if the data transfer performance isn't optimal. The new code is designed to be converted from this polling to using interrupts, so with a bit of luck it'll only take a short rev or two to get the performance up to where it should be.

A very important aspect to this project, which is mentioned in a couple places on the library functions page, is the caching strategy. The initial release will have only a very simple caching strategy. The file_cache function gives the application code complete control over what portions of what files and directories will be cached, and when the drive will be active vs in sleep mode. If you're interested in getting involved in the code, perhaps when the application level part is converted to C, put some thought into the caching strategy... what files to cache, how much of each, when to decide to uncache data, and when to hit the panic button (spin the drive up just in time before running out!)

Jan 22, 2001: I spent the whole day today working on the code that puts the cached clusters into a linked list and does lots of other little things that will allow the cached clusters to be used in useful ways. There are a lot of complicated cases to deal with. I split the caching operation into two functions, a "setup" function that doesn't actually do any loading, just takes care of lots of computation and stores info into the file descriptor table, and a "work" function that the main program calls repetitively until the file is completely cached. This scheme is much more efficient... it avoids seeking though FAT sectors unless absolutely necessary. Nearly all the code needed to get a file loaded into the cache is written, and tommorrow will be a major debugging session.

Today I exchanged emails with Tom Parker (who sent a patch for 0.5.1 to display long filenames), and I've wrote a fairly detailed description of how the main program will use these lower level functions. I added this text to the library functions page. If you're interesting in hacking on the code, please read this description in the "File/Directory Reading" section to get an idea of where the project is going and what low-level functions will (hopefully soon) be available for building cool features (playlists, ID3 tags, long filenames, etc). All this low-level restructuring doesn't actually do those cool features, but it'll make coding them possible. It will remove the defragment requirement, and it will give DRAM buffering, though the effectiveness of the buffering depends on how good the main program's scheme is for choosing what to request be loaded into the cache.

Also, several people have been asking about the LCD display recently... I have the 128x64 lumex display connected and some code that's able to write pixels at selected locations. I'm planning to work on the display once this major rewrite of the FAT32 and IDE code is working. I'm also thinking about making the board support cheaper text-only displays (the really cheap ones unfortunately are surplus and are not consistantly available, which sucks for putting a lot of design work into a board and the code). The lumex display itself if $45, and I'm hoping to make the adaptor boards for $25-30. I know this isn't cheap, but so far it's about the best I've been able to find for a pretty cool display that's not a while-supplies-last surplus item. In any case, without these more reasonable ways to deal with files and directories (and subdirectories), it just isn't too realistic to do much with a display, so this FAT32/IDE code needs to come first.

Jan 21, 2001: I've been working more or less round-the-clock this weekend, finally getting the FAT32 and IDE code re-written for caching with the DRAM. So much as happened to the code in the last couple weeks, and particularily in the last 48 hours, but it's getting late so I'll avoid a really long message like the one from a couple weeks ago.

Here is a text capture of the latest firmware, which is loaded up with dozens of messages that tell quite a bit about what the code is doing. I hope this give you a bit of an idea of where it's at. I'll add some comments in green to explain a bit about what it's doing.

I've a lot of momentum on the project right now, so I think I'm going to try to take a day or two off work and push to get a working firmware rev going. If I do manage to get a day or two off work, I'll update this page tommorrow.

    MP3 Player, Version 0.5.??, Jan 21, 2001             <-- not a real firmware rev, lotsa stuff still broken!
    Copyright (C) 2000, PJRC.COM, LLC

    Type 'QUIT' to return to the monitor

    Configuring Xilinx XCS10XL FPGA Chip: Ok
    Reseting IDE Devices
    Initialize Memory Manager                            <-- this actually initializes FAT32 and IDE drivers also :)
    Found 16 meg SIMM
    malloc 8 blocks: 0021 0022 0023 0024 0025 0026 0027 0028 
    Configuring STA013 MP3 Decoder Chip: .........Ok
    Waiting for Hard Drive to be ready
    .
    Found IDE Master
    Set multiple mode, status=50                         <-- the new IDE driver uses multiple mode... 

    Reading Master Boot Record
    Found FAT32 Partition at LBA = 0000003F              <-- these are (more or less) the same startup messages
    Reading FAT32 Volume ID
    Volume ID looks ok
    Sectors used for FAT tables: 00004C70
    Reserved Sectors: 0020
    First Data Sector at LBA = 00004CCF
    Cluster size is 32 sectors (each sector is 512 bytes),
    Clusters will be cached in 4 block groups (each block is 4096 bytes)
    Root directory starts at cluster 00000002
    Testing new FAT32 code:
    fopen, fd=0                                          <-- program opens root directory
    file_cache, fd=0, bytes 00005E03 to 00007E02         <-- program asks for a portion to be cached
      Req'd cluster offset 000001 to 000001              <-- the second cluster on this file is needed
      next_cluster, current=00000002
        search for FAT sector 00000000                   <-- FAT sector index 0 is needed to find this cluster
        FAT sector not found in list                     <-- this FAT sector isn't in the cache (yet)
        currently cached blocks w/ FAT sectors: 0000
        new block to insert into array at index=0000
        moving fat sector lookup array
    malloc 1 blocks: 0029                                <-- the memory to cache this FAT sector is malloc'd
    doing ide state: waiting for not busy
    doing ide state: idle
    ide: reading 4k at lba=0000005F into block 0029      <-- the IDE driver reads the FAT sector into the cache
    doing ide state: waiting for DRQ
    doing ide state: waiting for DMA complete
    doing ide state: waiting for not busy
    file_cache, fd=0, bytes 00005E03 to 00007E02         <-- program asks for data to be cached (again)
      Req'd cluster offset 000001 to 000001
      next_cluster, current=00000002
        search for FAT sector 00000000
          bin_search: begin=0000, end=0000, middle=0000
        FAT sector found in list at index=0000, blk=0029 <-- this time, the FAT sector is found in the cache
      read cluster 000073EC (offset 000001)
    malloc 4 blocks: 002A 002B 002C 002D                 <-- 16k (four 4k blocks) are allocated to hold the cluster
    doing ide state: idle
    ide: reading 4k at lba=00004CCF into block 002A      <-- IDE driver reads first part of the cluster
    doing ide state: waiting for DRQ
    doing ide state: waiting for DMA complete
    doing ide state: waiting for not busy
    doing ide state: idle
    ide: reading 4k at lba=00004CD7 into block 002B      <-- IDE driver reads second part of the cluster
    doing ide state: waiting for DRQ
    doing ide state: waiting for DMA complete
    doing ide state: waiting for not busy
    doing ide state: idle
    ide: reading 4k at lba=00004CDF into block 002C      <-- IDE driver reads third part of the cluster
    doing ide state: waiting for DRQ
    doing ide state: waiting for DMA complete
    doing ide state: waiting for not busy
    doing ide state: idle
    ide: reading 4k at lba=00004CE7 into block 002D      <-- IDE driver reads last part of the cluster
    doing ide state: waiting for DRQ
    doing ide state: waiting for DMA complete
    doing ide state: waiting for not busy
    doing ide state: idle
    doing ide state: idle                                What happens next, you may wonder...

...A lot more work is still needed, for example recognizing that the requested range is fully cached, correctly linking the clusters to a list so the reads from the file will work properly, handling cases where a latter part of the file is cached before the beginning, properly marking FAT sector per-file usage bitmaps (so that a call to fclose can deallocate the FAT sectors for that file if they aren't needed by other open files), a lot more testing (for example, the binary search has minimal testing because I haven't built any substantial lists of cached FAT sectors yet), and a new main program that actually uses this neat new stuff to achieve playback.

Still, it's pretty exciting to finally start getting some data cached, and using FAT sectors from the cache instead of looking them up on-the-fly.

Jan 3, 2001: Last night I did a bit more work on the code, mostly getting the just malloc'd FAT sector buffer added to the list of cached FAT sectors, and all the misc housekeeping details (I hope). Tonight I'll start on actually servicing the read requests. Will update this page later tonight it there's any really exciting news.

This recent news page was getting pretty long, and using up quite a bit of our limited server bandwidth, so I chopped all the news before Nov 20th and put it on the history page.

Jan 1, 2001: I spent most of the 3-day weekend writing, or at least trying to write the DRAM buffering support code. Robin and I also put together more MP3 player kits. I added a contribution to the STA013 page from Ed Schlunder (that'd been sitting in my inbox for a week) and they wrote the last major missing section.

The code in 0.5.1 and below works by reading one sector at a time. The code waits for the sector to be read and then give it to the STA013 chip for playing. That's very simple, and it's designed for when the FPGA didn't really support the DRAM and the only memory available was the 256 bytes in the 87C52 and a sector-sized fifo in the FPGA.

In the absence of a firmware release, I'll write a bit about how it's intended to work, so you can see a bit of what's going on. There is a "file_open" routine which is similar to a C library "fopen"... you give it the first cluster number of the file (which you get from the directory info together with the filename), and it returns a file descriptor byte. The current code allows 16 files to be opened. I might increase this to 32 files. "file_open" really only just initializes some info in memory that gets used by the other functions.

All the real work is done by a function called "file_cache", which I've been working on all weekend. You call file_cache with the file descriptor from file_open, a 32 bit beginning byte position, and a 32 bit length. This file_cache function has the job of getting that portion of the file cached into the DRAM. It never waits for data to be read! It always returns as quickly as possible. To get data cached, the program will need to call file_cache repeatedly until it returns a status bit that indicates the data is actually cached.

The first thing file_cache does is compute which clusters offset within the file are needed to satisfy the requested byte range. Then, it tries to follow the FAT cluster-chain to find the actual clusters on the disk those are. To do this, it does a binary search on an array of pointers to all the cached FAT sectors, to find the one holding each part of the list of clusters that leads to the one needed. If any of these looks fails to turn up the required FAT sector, then it is read.

How sectors are read is interesting. The file_cache routine calls "malloc_blocks" to get a block of memory that will hold the sectors. It sets a "read_pending" bit on a small data structure that describes the block, and then adjusts the array of pointers to the cached sectors, effectively adding this one to the list. It then writes a "read_request" into memory and returns to the main program with a status bit that indicates the file isn't cached yet.

For now, I'm having the main program run some code which polls this list "read_request" messages and either commands the drive to featch the sectors, or begins a transfer of the sectors (using DMA) to the memory (which was already malloc'd by whatever wrote the read_request message), or sees that the DMA is done and clears the "read_pending" bit, removes the "read_request" and sets up for the next request to the drive. Right now this is a simple routine that the main program calls, but later when this stuff is working, this will turn into an interrupt routine. Many other speed-ups will happen evenually (and appear as TODO comments in the code), but the right now this is a major restructuring of the way everything runs and the idea it to just get it going in a non-optimal way.

The "file_cache" routine keeps getting called (by the main program), and when the FAT sectors are in memory, it'll locate the required cluster numbers, and create similar read_requests for them. (they get stored in a link-list from the struct indexed by the file descriptor, not together with the FAT sectors) When it has requested the last read for the last cluster, it'll return a status code that the file is cached (or at least will be very soon, and no more file_cache requests are needed).

I'm planning two "file_read" functions... one that copies a small part into a buffer allocated by the main program, and another the returns a pointer to the next 4k block of cached data. (the more difficult read-into-buffer is partially written) Both of these will only read data that's already cached. The only function that causes disk activity is "file_cache". The "read" that copies will be useful for building a nice routine that parses directories better (including long filenames), and it'll be useful for reading ID3 tags, playlists and other user interface required data. The block-based read returns a pointer to a cached block without copying anything, and is intended mostly for playback, together with a "play_reqest" list, similar to the "read_request" list for the disk drive.

If this all sounds complicated, that's because it is! It's been a long uphill battle to get this far. It's a lot harder to build a nice general purpose memory-managing interface like this than it is to just read sectors one-at-a-time. There is still much coding to do, but the good news is that how it's all going to work together is really becoming much clearer, and a substantial portion of file_cache (and the lower level malloc, bin_search, and other functions) are written and seem to be working. I could go on about the details, but maybe I'll just say a little bit more about how I'm planning to use these functions once they're working. I haven't updated the library functions page yet...

Imagine the (hopefully very near) future when these functions are working.... the main program will open the main directory, call to have it cached, then parse for the first file. It'll open that file, call to have it cached, then read the first several dozen blocks and generate "play_request"s for them. Then it'll open the next file files, and request them to be cached. It'll probably monitor what portion of the memory is still free as it does this, and perhaps when available memory gets under some threshold, start opening a lot more files, but only requesting the first portion and perhaps the last portion (ID3 tag) to be cached. When these requests nearly consume all the memory, it'll generate a special "read_request" that tells the IDE driver to spin down the drive and put it into full sleep mode. All the while, the main program will be monitoring if there is space to enter more "play_request"s and keep reading more blocks of the current file to generate them. As the blocks are used, a "file_uncache" function gets called to free the memory, and when a file is completely finished, "file_close" completely frees all the memory used by that file and returns its file descriptor back to the list of available to be opened again. Some sort of estimate of how much more playtime is cached needs to be made as the blocks are played, and when it gets low, more files are opened and the "cache_file" is called, causing the drive to spin up and read more data. Because cache_file can cache small portions, a number of files into the directory (or playlist :) can be cached with just enough in memory to start them playing and have enough time to spin-up the drive to get the rest. It'll also be possible to have the part of the file with the ID3 tag cached, but not the rest of the file. The idea is to build a good library of functions to manipulate files and more or less automatically handle all the memory allocations, so that the main user-level application can be built to do all sorts of really nice things.

Well, that's all a lot of vapor, but it really is becoming much clearer how these functions are going to work "behind the scene", and a good part of the code is running. A lot of the difficult groundwork, like defining the structures in memory that'll keep track of all this stuff are in place. I'll try to keep this page updated with news and as soon as some of this stuff is working in a somewhat useable way, I'll get a firmware rev made.

Dec 28, 2000: I didn't get any coding done over the X-mas weekend, but we did (finally) get some more bare circuit boards. We also got more of the 8051 dev boards, just as we ran out of those boards :) We spent some time assembling more boards. Last night Robin printed more labels for the kits. I think we have all the other parts, so with an afternoon of sorting and counting parts, we should finally have the kits available again!

Dec 20, 2000: This evening I answered emails, lots of them. I'm going to give up on a group of really old ones, from early August to the first week of November. (I did answer lots during that period, but not all) If you sent me a message back then and I didn't answer, I'm sorry. I'm (finally) caught up now, and I think I'm getting better about keeping up with the higher volume of email since the slashdot article. It feels good to finally have an empty inbox!!!! I'm going to try and keep it that way.

Dec 19, 2000: Yesterday Peter Kovacs added a couple more links at his mp3projects.com site, particularily to the new Using the STA013 page. I started this page a couple weeks ago, since I've been getting quite a bit of email (mostly from students) asking how to use the STA013. Now that it's going to be getting a good number of hits, I figured I ought to at least get some good info onto it.

Last night I built that little breadboard and added the photos, and I spent a quite a bit of effort to make a few low-bitrate test clips, that fit into 32k of memory and actually have several seconds of a recognizable line of a well-known song. Tonight I added the four little schematic images.

Dec 17, 2000: I've been working on the firmware this weekend, and the firmware page now has version 0.5.1. I finally added the code for the volume and random play buttons. I really should have done it a long time ago (sorry to keep you waiting so long). I also added a patch from Dave Johnson that fixes the bug with the play/pause button (thanks Dave). I changed ide_init to automatically detect if the drive is an IDE master or slave. If the memory manager doesn't find a SIMM, the it will attempt to run version 0.1.1, which is also included.

Version 0.5.1 still doesn't do any significant buffering and it still needs the drive to be defragmented. I'm making some progress there... most of the memory management library functions are included inside this firmware, though they're mostly untested.

Dec 14, 2000: I'm sorry I haven't updated this page in the last two weeks. I've been a bit busy and saddly I haven't been putting as much time into this project as I want to. To make up for that, here's a bit of kind-of good news...

I just posted a DRAM test firmware release to the firmware page. Don't get too excited, this firmware works almost exactly like 0.1.1 (no significant buffering), but it does use the DRAM (a very tiny portion), with DMA from the drive to DRAM and DMA from the DRAM to the MP3 decoder chip. If you have a bit of time, I'd really like to hear how it works with your SIMM and hard drive. Also, does the SIMM auto-detect find the correct size of your SIMM? If you have a laptop drive that frequently "skips", does it perform better or worse with this new version? (my Hitachi DK23AA-12 is mysteriously working better) Is the audio quality the same, worse or better? Does it seem to use more power than 0.1.1? Everything is supposed to look the same as 0.1.1 (including the play-play-pause bug), so if you notice any differences please let me know.

I rev'd the firmware to version 0.5.0. The idea behind this is that I'll probably back-port a few features to the 0.1.x firmware, for anyone that doesn't want to use a SIMM. Also, getting the hardware config more or less finished is a big step, so 0.5.0 seemed cool. There's still much work to be done in firmware to actually take advantage of all these new capabilities. Writing all the code to