Jump to content
IGNORED

Smelly Adventures


cubanismo

Recommended Posts

2 hours ago, Zerosquare said:

if you have a short you can't clear, it's better not to insist. Instead, desolder the IC (using hot air or low-temperature solder like ChipQuik), clear the short, then resolder it. It's annoying but less risky.

Yes, this sounds like sound advice.  If the board hadn't been so compromised already with the lifted pads and whatnot, I would have gone that route for sure.  Possible I still should have, and I may still give it a shot if I get bored enough.

Link to comment
Share on other sites

  • 4 weeks later...

A few updates here:


First, as promised, the Linux port of the bjlSkunkFlash bootstrapping and verification tools:

 

  https://github.com/cubanismo/bjlSkunkFlash

 

Next, an update on my further experimentation and modification.  Why sit here happy with a working skunk when I can risk ruining it by tinkering and soldering a bunch more crap onto it?

 

The nice thing about the Rev. 4 and Zaxon Skunkboards is they have a serial EEPROM on them so if you're taking the liberty of using them for playing games now and then rather than developing, or if you just want to add save support to your under-development project, you're all set: It works just like the standard 128 byte EEPROM on most production cartridges.  However, there's only one EEPROM, but (for games <6MB) two banks of flash on the Skunk, so if you switch over to the other game and save anything there, it'll clobber whatever was in the EEPROM from the first game.  No bueno.  Also, if you're playing a ROM from one of the select few cartridges that use 1024 or 2048 byte EEPROMs, you're out of luck.  So what if we could add another EEPROM and toggle between the two?  Genius, right?  OK, maybe just obvious, but I was pretty sure I knew how it could be done rather easily.  Remember before that I'd noted there were several unused pins on the Cypress chip when I lifted their pads off the PCB?  That was the inspiration really: Was it possible some of those were unused GPIOs I could use to select between two different EEPROMs?  I spent a lot of time staring at the Cypress EZHost documentation and the Skunk PCB in FreePCB, and it turns out that hunch was correct, barely: There are two completely unused GPIOs I could use, and 2 was the number I needed to do it simply.  Unfortunately, they weren't the ones over where I lifted the pads on my failed board.  They were buried over near the JTAG header, and routing them over to the free space on the right side of the board where the Serial EEPROM was on the Rev. 4 boards was a serious undertaking.  To get them to toggle between the two chips, I wanted to route them into the chip select lines of the Serial EEPROM chips: Toggle the GPIO high to select the chip, low to disable it.  However, there was an additional complication: The Jaguar doesn't seem to just leave the Serial EEPROM enabled all the time itself, since it's just connected up to some of the Jaguar's own GPIO lines and clocked manually.  Those lines might  be needed for other stuff at other times, so I needed to AND the EZHost GPIO signals with the Jaguar's own chip select signal, and that meant adding yet another IC to get some AND gates.  The Skunk PCB was already pretty crowded, so I was worried this might be a dealbreaker.  However, I managed to find a chip that would *just* fit using an XSON8 package.  Several hours of furiously learning FreePCB later, I'd managed to route all this, and think I have a functional design.  However, is the logic actually correct?  I realized it was probably better to prototype on my existing Skunk board before dropping $50-100 and waiting 2-3 weeks on some prototype PCBs.  Here's what that looked like.

 

First, the hard part: I had to solder some wires onto the two tiny GPIO pins on the Cypress EZHost chip without shorting it with the neighboring pins:

 

skunk_build_30.thumb.jpg.fc67b62e10565084b78f01a4ac3a3c9b.jpg

 

skunk_build_31.thumb.jpg.044ebfd96dafc1fd2e10f465089934fa.jpg

 

skunk_build_32.thumb.jpg.4779cdd873fff6c286d302af7dc61a26.jpg

 

These pics are from the working board, but I practiced first on the broken board.  This took some serious holding of breath and cussing, but I managed to get them secured without shorting anything.  If you're doing this yourself, note I used 30AWG wrapping wire that I stripped and pre-tinned, then just pressed it up against the pins and touched the soldering iron to it a bit.  It's critical you have your soldering tip in just the right state.  I looked at it under my magnifying light carefully before bringing it near the joint each time.  It should be tinned but have just about the thinnest coat possible of solder on it.  If there's a little bubble or streak hanging off, that's going to jump onto your chip and bridge the tiny pins right away, which is what happened to me twice when practicing.  If that happens, goto solderWick and try again.  If you can't get the damn thing to stick, try dipping the tinned wire in a bit of flux first, or re-tinning it to get a little more solder on it.  Resist putting more solder directly on your iron!

 

The next part was easier: Break the connection between the chip-select pin on the existing EEPROM on the board and connect wires to route the end coming from the Jaguar through our own chip select logic and back again.  Clipping leads off of perfectly-good chips always makes me cringe, but here it goes:

 

skunk_build_33.thumb.jpg.c813c29ecdc3f15ad60a66a9e50ff358.jpg

 

skunk_build_34.thumb.jpg.ddc196737691ae3d8493a55722befa93.jpg

 

I'd recommend hot glue or something even stronger like super glue or epoxy if you're going to do this as a permanent mod, but I used some electrical tape to secure the wires in place a bit for now.  Next, I soldered some SMT chips for the AND gate IC (I used a MSOP package instead of the tiny XSON8 one for prototyping) and the additional Serial EEPROM (I used an additional 93C46/128 byte chip for now to make testing simpler, but they're pin-compatible with the bigger chips, so the HW side will be the same either way) onto some SparkFun prototyping PCBs so I could plug them into a breadboard:

 

skunk_build_35.thumb.jpg.2624d6aa7ee6e041421d2f0853001856.jpg

 

Sorry this picture came out a little blurry, and nevermind the mess on the left side of that MSOP chip: I think I ordered a TSOP mount instead of MSOP, thinking they'd be compatible since the pin pitch is the same, but the MSOP is apparently narrower and the pins didn't quite reach the pads on each side, though it's frustratingly close.  Seems like they could have just extended those giant pads a tiny bit further and made it work with both packages.  I laid down a bit of wrapping wire to bridge it on one side, messed it up several times, etc., but it worked out in the end.  Better than waiting another few days for another digikey order to come in.

 

Next we need to route all the Serial EEPROM data and clock lines from the skunk PCB out to the second Serial EEPROM, so time to attach even more wires to the existing chip:

 

skunk_build_36.thumb.jpg.fe759bb82768b32276fefeefc931faa0.jpg

 

And we're done.  Here's the whole thing wired up on my workbench, as well as with the power wired up to the Skunkboard's VCC3 and Ground circuits via the JTAG connector while in my Jaguar:

 

skunk_build_37.thumb.jpg.54d756dbe0bab0de76500c6915a0c420.jpg

 

skunk_build_38.thumb.jpg.bf296b59306401e244c1fc05461653fa.jpg

 

Now I needed some software to toggle the GPIOs on the EZHost chip.  Luckily, there's some sample code available: JCP uses an EZHost GPIO to toggle the reset signal when you run 'jcp -r'.  I copied that function over and edited it to toggle GPIO25/28 instead; the lines I used for my logic.  This didn't actually work as planned at first: I couldn't connect to the skunk after running the new command to flash a program or even check for life with -s, and it was only working on GPIO25.  A desperate scan of the EZHost datasheet revealed the problem with GPIO28: It's wired up to the UART TX signal by default.  Disabling the EZHost UART got the pin toggling.  I couldn't connect because I'd copied the call to LockBothBuffers() from the reset function, which apparently prevented later commands from running.  Removed that, and it was perfect: Two separate EEPROMs which I could manually choose between by running a simple jcp command before choosing which game to start or uploading code.  The setting doesn't persist across resets or power cycles yet, but the basic logic works.

 

But wait, there's one more thing!  What's better than two EEPROMs?  Infinite EEPROMs!  OK, so I'm being dramatic.  This was always part of the plan.  I wrote some trivial skunklib programs that read/write the Serial EEPROM contents to a file on the host computer, and these are actually what I used to verify the logic above.  jcp -c e2pget.cof will save the EEPROM content to eeprom.e2p on the host, where you can rename it and archive it along side your ROMs for later restoration or copy it onto your gamedrive (format should be the same, just a raw byte dump) when that comes.  jcp -c e2pput.cof writes eeprom.e2p on the host to the currently-selected EEPROM on the board.  Of course, this works independently of my HW mod if your skunkboard already has a Serial EEPROM on it, so anyone with a Zaxon, santosp "Rev. 4" skunkboard, or self-modified skunkboard with a Serial EEPROM dangling off of it can make use of these if they don't already have a similar tool.  Here's the github link for these little programs in case anyone else might find them useful as-is:

 

  https://github.com/cubanismo/e2pmgr

 

The makefile requires my SDK environment:

 

  https://github.com/cubanismo/jaguar-sdk

 

This is all well and good, but it's still just prototype-level quality and UI.  The real goal is to merge the e2pput/e2pget functionality into jcp itself so you can just add an option when flashing game roms to say "Flash this EEPROM content as well, and backup the existing content to this file first", and save the desired EEPROM "bank" on the skunk for each flash bank, such that when you start a game by pressing up or down as usual, it automatically enables the EEPROM associated with that bank first, as well as having one small (standard) and one large EEPROM rather than two small ones, so all games can be supported.  And of course, now that I know the basic logic works, I can polish off those PCB designs and hopefully get some prototypes that don't require dangling a breadboard off the side of my Jaguar ?

  • Like 2
Link to comment
Share on other sites

13 minutes ago, cubanismo said:

A few updates here:




First, as promised, the Linux port of the bjlSkunkFlash bootstrapping and verification tools:

 

  https://github.com/cubanismo/bjlSkunkFlash

 

Next, an update on my further experimentation and modification.  Why sit here happy with a working skunk when I can risk ruining it by tinkering and soldering a bunch more crap onto it?

 

The nice thing about the Rev. 4 and Zaxon Skunkboards is they have a serial EEPROM on them so if you're taking the liberty of using them for playing games now and then rather than developing, or if you just want to add save support to your under-development project, you're all set: It works just like the standard 128 byte EEPROM on most production cartridges.  However, there's only one EEPROM, but (for games <6MB) two banks of flash on the Skunk, so if you switch over to the other game and save anything there, it'll clobber whatever was in the EEPROM from the first game.  No bueno.  Also, if you're playing a ROM from one of the select few cartridges that use 2048 or 4096 byte EEPROMs, you're out of luck.  So what if we could add another EEPROM and toggle between the two?  Genius, right?  OK, maybe just obvious, but I was pretty sure I knew how it could be done rather easily.  Remember before that I'd noted there were several unused pins on the Cypress chip when I lifted their pads off the PCB?  That was the inspiration really: Was it possible some of those were unused GPIOs I could use to select between two different EEPROMs?  I spent a lot of time staring at the Cypress EZHost documentation and the Skunk PCB in FreePCB, and it turns out that hunch was correct, barely: There are two completely unused GPIOs I could use, and 2 was the number I needed to do it simply.  Unfortunately, they weren't the ones over where I lifted the pads on my failed board.  They were buried over near the JTAG header, and routing them over to the free space on the right side of the board where the Serial EEPROM was on the Rev. 4 boards was a serious undertaking.  To get them to toggle between the two chips, I wanted to route them into the chip select lines of the Serial EEPROM chips: Toggle the GPIO high to select the chip, low to disable it.  However, there was an additional complication: The Jaguar doesn't seem to just leave the Serial EEPROM enabled all the time itself, since it's just connected up to some of the Jaguar's own GPIO lines and clocked manually.  Those lines might  be needed for other stuff at other times, so I needed to AND the EZHost GPIO signals with the Jaguar's own chip select signal, and that meant adding yet another IC to get some AND gates.  The Skunk PCB was already pretty crowded, so I was worried this might be a dealbreaker.  However, I managed to find a chip that would *just* fit using an XSON8 package.  Several hours of furiously learning FreePCB later, I'd managed to route all this, and think I have a functional design.  However, is the logic actually correct?  I realized it was probably better to prototype on my existing Skunk board before dropping $50-100 and waiting 2-3 weeks on some prototype PCBs.  Here's what that looked like.

 

First, the hard part: I had to solder some wires onto the two tiny GPIO pins on the Cypress EZHost chip without shorting it with the neighboring pins:

 

skunk_build_30.thumb.jpg.fc67b62e10565084b78f01a4ac3a3c9b.jpg

 

skunk_build_31.thumb.jpg.044ebfd96dafc1fd2e10f465089934fa.jpg

 

skunk_build_32.thumb.jpg.4779cdd873fff6c286d302af7dc61a26.jpg

 

These pics are from the working board, but I practiced first on the broken board.  This took some serious holding of breath and cussing, but I managed to get them secured without shorting anything.  If you're doing this yourself, note I used 30AWG wrapping wire that I stripped and pre-tinned, then just pressed it up against the pins and touched the soldering iron to it a bit.  It's critical you have your soldering tip in just the right state.  I looked at it under my magnifying light carefully before bringing it near the joint each time.  It should be tinned but have just about the thinnest coat possible of solder on it.  If there's a little bubble or streak hanging off, that's going to jump onto your chip and bridge the tiny pins right away, which is what happened to me twice when practicing.  If that happens, goto solderWick and try again.  If you can't get the damn thing to stick, try dipping the tinned wire in a bit of flux first, or re-tinning it to get a little more solder on it.  Resist putting more solder directly on your iron!

 

The next part was easier: Break the connection between the chip-select pin on the existing EEPROM on the board and connect wires to route the end coming from the Jaguar through our own chip select logic and back again.  Clipping leads off of perfectly-good chips always makes me cringe, but here it goes:

 

skunk_build_33.thumb.jpg.c813c29ecdc3f15ad60a66a9e50ff358.jpg

 

skunk_build_34.thumb.jpg.ddc196737691ae3d8493a55722befa93.jpg

 

I'd recommend hot glue or something even stronger like super glue or epoxy if you're going to do this as a permanent mod, but I used some electrical tape to secure the wires in place a bit for now.  Next, I soldered some SMT chips for the AND gate IC (I used a MSOP package instead of the tiny XSON8 one for prototyping) and the additional Serial EEPROM (I used an additional 93C46/128 byte chip for now to make testing simpler, but they're pin-compatible with the bigger chips, so the HW side will be the same either way) onto some SparkFun prototyping PCBs so I could plug them into a breadboard:

 

skunk_build_35.thumb.jpg.2624d6aa7ee6e041421d2f0853001856.jpg

 

Sorry this picture came out a little blurry, and nevermind the mess on the left side of that MSOP chip: I think I ordered a TSOP mount instead of MSOP, thinking they'd be compatible since the pin pitch is the same, but the MSOP is apparently narrower and the pins didn't quite reach the pads on each side, though it's frustratingly close.  Seems like they could have just extended those giant pads a tiny bit further and made it work with both packages.  I laid down a bit of wrapping wire to bridge it on one side, messed it up several times, etc., but it worked out in the end.  Better than waiting another few days for another digikey order to come in.

 

Next we need to route all the Serial EEPROM data and clock lines from the skunk PCB out to the second Serial EEPROM, so time to attach even more wires to the existing chip:

 

skunk_build_36.thumb.jpg.fe759bb82768b32276fefeefc931faa0.jpg

 

And we're done.  Here's the whole thing wired up on my workbench, as well as with the power wired up to the Skunkboard's VCC3 and Ground circuits via the JTAG connector while in my Jaguar:

 

skunk_build_37.thumb.jpg.54d756dbe0bab0de76500c6915a0c420.jpg

 

skunk_build_38.thumb.jpg.bf296b59306401e244c1fc05461653fa.jpg

 

Now I needed some software to toggle the GPIOs on the EZHost chip.  Luckily, there's some sample code available: JCP uses an EZHost GPIO to toggle the reset signal when you run 'jcp -r'.  I copied that function over and edited it to toggle GPIO25/28 instead; the lines I used for my logic.  This didn't actually work as planned at first: I couldn't connect to the skunk after running the new command to flash a program or even check for life with -s, and it was only working on GPIO25.  A desperate scan of the EZHost datasheet revealed the problem with GPIO28: It's wired up to the UART TX signal by default.  Disabling the EZHost UART got the pin toggling.  I couldn't connect because I'd copied the call to LockBothBuffers() from the reset function, which apparently prevented later commands from running.  Removed that, and it was perfect: Two separate EEPROMs which I could manually choose between by running a simple jcp command before choosing which game to start or uploading code.  The setting doesn't persist across resets or power cycles yet, but the basic logic works.

 

But wait, there's one more thing!  What's better than two EEPROMs?  Infinite EEPROMs!  OK, so I'm being dramatic.  This was always part of the plan.  I wrote some trivial skunklib programs that read/write the Serial EEPROM contents to a file on the host computer, and these are actually what I used to verify the logic above.  jcp -c e2pget.cof will save the EEPROM content to eeprom.e2p on the host, where you can rename it and archive it along side your ROMs for later restoration or copy it onto your gamedrive (format should be the same, just a raw byte dump) when that comes.  jcp -c e2pput.cof writes eeprom.e2p on the host to the currently-selected EEPROM on the board.  Of course, this works independently of my HW mod if your skunkboard already has a Serial EEPROM on it, so anyone with a Zaxon, santosp "Rev. 4" skunkboard, or self-modified skunkboard with a Serial EEPROM dangling off of it can make use of these if they don't already have a similar tool.  Here's the github link for these little programs in case anyone else might find them useful as-is:

 

  https://github.com/cubanismo/e2pmgr

 

The makefile requires my SDK environment:

 

  https://github.com/cubanismo/jaguar-sdk

 

This is all well and good, but it's still just prototype-level quality and UI.  The real goal is to merge the e2pput/e2pget functionality into jcp itself so you can just add an option when flashing game roms to say "Flash this EEPROM content as well, and backup the existing content to this file first", and save the desired EEPROM "bank" on the skunk for each flash bank, such that when you start a game by pressing up or down as usual, it automatically enables the EEPROM associated with that bank first, as well as having one small (standard) and one large EEPROM rather than two small ones, so all games can be supported.  And of course, now that I know the basic logic works, I can polish off those PCB designs and hopefully get some prototypes that don't require dangling a breadboard off the side of my Jaguar ?

Holy sh*t, that's mind blowing. Exceptional work.

Put me down for 3 :P

  • Like 2
Link to comment
Share on other sites

  • 3 weeks later...

Several bits of learning and news to share here.

 

First, the mystery of why skunkbios_3.0.1-noverify.COF failed to flash when I was bootstrapping my first working board is solved, and it's rather silly. It's because it was stuck trying to connect to the jcp console.  I realized this when I saw there's also a -noconsole variant in @Tursi's skunk_bios github repository here.  I verified plugging in a USB cable while running bjlSkunkFlash and running "jcp -c" when it gets stuck gets the -noverify variant working.

 

Next, why was drag soldering so easy on my practice boards but super-hard on these Skunk PCBs?  Because the Skunk PCBs don't have solder mask between the pads and the boards are very likely made using a low-quality substrate.  Here's a close-up look at a fresh one (Thanks @Saturn for sending these over):

 

skunk-rev4-pads.thumb.jpg.e2e40d79b22efa9c1f14d7685ba6cdfa.jpg

 

See how the boards are blue everywhere except around the gold pads where chips are mounted?  That blue stuff is the solder mask, and it repels solder like oil repels water.  However, it is difficult to manufacture boards with tiny solder mask bits between copper pads.  The process that lays down the mask layer over the board needs to be precisely aligned or the mask will overlap the copper, giving you bumps that could cause your chip to not cleanly contact the pad.  To account for that, you have to widen the "cut-out" for your pads in the solder mask when designing the PCB.  Different manufacturers have different abilities, so if you're using a cheap manufacturer, you have to enlarge the opening more than for others.  Further, if you try to put down too thin a sliver of solder mask, it might not result in a nice flat line of mask, but rather could splinter or bubble.  This also varies, I believe mostly based on the quality of the solder mask material and process used by the manufacturer.  Taken together, you basically get some minimum pad spacing for which you can lay down a solder mask between the pads.  If the spacing is lower than that, you don't get solder mask between those pads.  Some manufacturers will even fix this up for you and remove solder mask regions too small for them to manufacture.  These days, good manufacturers can lay down a mask between pads with the relatively fine spacing (0.2mm) used here, but the skunkboard design files were very conservative by today's standards and had a very large clearance around their pads.

 

TL;DR: No solder mask here means solder is more likely to bridge across pins placed on these pads when drag soldering.

 

The "low quality substrate" bit relates to why pads were lifting off these things like crazy.  Granted, I was pretty crap at soldering when I started off here and I'm still not great.  What that means is I was keeping the iron on the board a lot longer than was ideal, especially when trying to use solder wick to remove solder bridges when I messed up, partially caused by the lack of solder mask.  If you're using cheap substrate, such as TG-130/TG-140, it will start to burn pretty quickly, and then the pads will lift right off of it.

 

The owner of Osh Park goes into detail about these and other issues you'll run into manufacturing your boards at a cheap fab in this reddit post.

 

How did I learn all this?  Well, I've been busy.  I finished laying out my changes to the skunk PCBs and was looking into getting some prototypes built.  I learned all of the above while researching and comparing the capabilities of the various PCB manufacturers members here recommended.  Ultimately I decided to go with Osh Park for the initial prototype boards, as @grips03 recommended.  It didn't hurt that all Osh's boards are purple.  My younger daughter's favorite color is purple, and while I cycled through the various solder mask colors in a gerber viewer with her on my lap, she insisted the boards looked best in purple.  Everywhere else, purple costs a little extra.  At Osh, it's your only option!

 

I sent everything off about a week and a half ago, and got a package from Osh on Monday.  Behold, Purple Skunks!

 

purple_skunk-1.thumb.jpg.be31125af476b2ed89a21ddd7a0427b3.jpg

 

Note I couldn't resist tweaking the Skunk logo a little ;-)

 

The boards needed a little cleaning up.  They had some nibs on them from where they were attached to the others in the panel, and they weren't beveled (Osh doesn't offer beveling).  Nothing a little sanding followed by an alcohol wipe couldn't fix:

 

purple_skunk-2.thumb.jpg.8eff06658aabd41ae46bf4b7e15572d3.jpg

 

Note I did this outdoors with a respirator on.  PCB dust is nasty!

 

As mentioned above, the key to my changes was routing some GPIOs from the EZHost USB controller chip through an AND gate to combine them with the Jaguar's GPIO line used to toggle the chip select line on the Serial EEPROM to allow enabling only one of two Serial EEPROM chips at a time.  To fit this on the available sliver of PCB real estate left on the skunk PCBs, I had to use a tiny XSON8 package, and I was pretty nervous about being able to lay down tiny enough globs of solder paste by hand to get this working without shorting pins.  However, I got it working.  I did short at least one pin on all 3 boards, but I was able to easily clear it by covering the exposed portion of the pads with some flux and touching my soldering iron tip to them. This pulled enough solder out from under the chips to clear the shorts all but once, and in that case, I just applied more flux and hit it with the hot air gun again to get the solder to flow out onto the pads.  Here's the chip sitting in a little-but-not-little-enough puddle of solder paste:

 

purple_skunk-3.thumb.jpg.7d07a6a64b23266f071b83771043e56f.jpg

 

And after reflow + fixups:

 

purple_skunk-4.thumb.jpg.f74e966b2a87d55b69e57cb773524a7c.jpg

 

As you can see, the whole IC package is about the size of an 0603 SMD component.

 

After soldering all the solder-paste components (This XSON8 IC, which is U7 on my layout, and U4, the USB power regulator IC with a heatsink pad on the bottom), I sprinted through the build of a single board to verify everything was working:

 

purple_skunk-5.thumb.jpg.3e98f36a7fd9af1eda3f602da743d1d5.jpg

 

Here's a tip if you're doing some drag soldering: After you've tacked the chip in place, hit the pins and pads with the rework hot air gun on a relatively low setting for a few seconds to pre-warm them.  Then quickly cover everything in flux and do the drag.  Warming the pins and pads seems to prevent the solder from instantly solidifying when it touches them, allowing it to drag along with the iron as desired.  This is probably all the more important when working with a relatively cheap iron like I am, since it can't compensate for encountering the thermal mass of a pad connected to a ground plane or even a handful of pins on an IC.  If you don't have a hot air gun, don't despair if your first drag across the pins leaves a mess of bridged pins.  Just quickly reapply flux if it all burnt up in the first pass, and drag the iron (very lightly tinned, but not naked) over it again to drag the solder away from the gaps.  The pins & pads should have been warmed significantly by the first pass, achieving roughly the same affect as pre-warming them with the hot air gun, and you should get a much cleaner drag, with the solder flowing onto the pads and pins and away from the gaps.  Repeat if needed.

 

After I got all the critical components on:

 

purple_skunk-6.thumb.jpg.cb7165296fdfcd8801d8285a1db431d6.jpg

 

I stopped to test basic functionality.  I was able to find the Cypress chip via USB, flash the CPLD, and flash the BIOS without any hitches, so I soldered on the remaining components:

 

purple_skunk-7.thumb.jpg.6b182c0887002b2acd40b68e9ebe4680.jpg

 

And ran it through the test2.sh bringup test suite, which it passed.  I ran it once more to be sure, and went to bed.  It took me roughly 4.5 hours /(~2.5 @Shinto Jaguar game-by-game podcasts), of non-stop soldering and futzing with JTAG and stuff to get this far, and I was exhausted by the end of it.  This was the first time I'd built an entire board (plus part of two others) in one sitting.

 

The next day, after a good cup of coffee, work, and family stuff, it was time to test the actual changes I'd made.  I'd improved on the software I wrote above by integrating the EEPROM dumping and writing directly into a build of JCP, and merging in some code I found by @Songbird (Thanks again!) to support 93C86/2048 byte EEPROMs as well since the board above has one 93C46 (128 byte, standard for non-homebrew Jaguar carts) and one 93C86 (Many newer homebrew carts use this).  The updated EEPROM code is already on my e2pmgr github repo, and I'll post the updated jcp code soon.  It needs a little cleanup, as I still have to select between 128 and 2048 byte support at build time right now.

 

After a bit of debugging, it all worked flawlessly, so all the new HW functionality has been verified.  I'm quite pleased with this, as is my older daughter, who is also fond of purple, and just shouted "PURPLE!" when I showed her the finished board yesterday morning.  It's my first attempt at PCB layout and manufacturing, and it went off without a hitch.

 

I took a break to do some non-Jaguar stuff tonight and write this up, and I'm going to read up on all the local candidates and propositions and do my vote-by-mail thing tomorrow night, but the next thing I'm going to attack is the BIOS.  I have a scheme worked out to stash EEPROM selection settings in an unused sector of the BIOS area of bank 2 (Or the top 2MB when using 6MB mode), but toggling the GPIOs from the skunk didn't go as smoothly as I'd hoped.  You apparently can't write to the EZHost control registers using HPI DMA mode like you can the other on-chip memory addresses.  Doing so just locks up the EZHost chip, as it appears someone else already learned, based on comments in usb/main.c in the skunkboard full release archive.  Luckily, there's an HPI mailbox protocol you can use for this instead, and skunk CPLD appears to support it.  I have all the code written up to do things that way, and it runs without reporting any errors, but... it's not actually toggling the GPIOs for some reason.  Debugging needed.

 

Also, at some point, I'll build up the other two boards, and perhaps more if others are interested.  If I order more, it'll have to be a relatively large batch to be economical (Basically, it costs about the same to order 50 as it does to order 5), so I'll certainly have spares, and if I can sell a handful or so, the whole project would be self-financed. However, we'll have to see if anyone still wants a skunkboard now that game drives are well and truly just around the corner.

 

Regardless, I'll be pushing my full PCB designs, BOM, updated JCP code, and hopefully, updated BIOS code (once it's working) to github soon as well, along with very, very verbose notes for anyone who really wants to dive into the details (I know, who knew it could get even more verbose than my posts here?), all public domain like the existing skunk files.

  • Like 11
Link to comment
Share on other sites

Got the BIOS-side EZHost GPIO manipulation routine debugged, and have my board flashed to a brand new v4.0.0 BIOS now, which:

 

-Initializes the GPIOs to select the 128B Serial EEPROM bank on boot (Minimum functionality required to make the Rev.5 boards no worse than a Rev. 4 or Zaxon board out of the box).

-Lets you select EEPROM 1 by pressing D-Pad Left (Screen will flash yellow to acknowledge)

-Lets you select EEPROM 2 by pressing D-Pad Right (Screen will flash deep blue to acknowledge)

 

From there you can use the usual D-Pad Up/Down or JCP upload to boot your EEPROM-aware code using the selected EEPROM.  The EEPROM selection can also be toggled from JCP, and JCP can upload/download EEPROM content to the active EEPROM chip.  I still need to add the 2048B EEPROM support to the JCP save/restore functions.  Currently, the upload/download is still 128B only.  The code is written and works when run manually as a stand-alone program, it just needs to be integrated with JCP.

 

Had some fun tonight testing this with @CyranoJ's BIOPEDE in one flash bank, Val d'Isère Skiing and Snowboarding in the other: Pressed Right then Up to launch BIOPEDE with saved high scores (Thank god the defaults are low, or I would have been testing forever.  Turns out I'm terrible at this game), Left then Down to launch Skiing & Snowboarding with saved controller configs & run unlocks/progress.  JCP to back up/restore the save game data afterwards. Pretty sweet.

 

I'll test this a bit more, make one more cleanup pass, then make a release with this base functionality before I attack utilizing the unused flash regions to store EEPROM selection defaults and/or EEPROM<->flash save/restore from the BIOS.  The JCP save/restore functionality will be useful for anyone with EEPROMs on their skunk, the JCP & BIOS EEPROM toggling stuff will only be useful for me unless others want Rev.5 skunks.  For the BIOS, my plan is for the currently-working base functionality to be Skunk BIOS 4.x.x, and the enhanced/flash-aware functionality to be Skunk BIOS 5.x.x, conveniently bringing the version number back in line with the board revision number ;-)

  • Like 6
Link to comment
Share on other sites

  • 2 weeks later...

Some updates for those following the nitty-gritty:

 

As mentioned on the general interest thread, I decided to tweak the layout a bit and order a 2nd prototype (RC2) set of boards to verify it. There was no functional issue, but I noticed the boards wouldn't fit in a standard Jaguar cartridge case with a serial EEPROM soldered on because some support structures collided with the serial EEPROM chip. The same is true of the Rev. 4 boards in fact. I very much wanted to ignore this, since I personally have no interest in putting the boards in a standard case (They don't fit with the extra USB connectors soldered on anyway), but I imagine someone is going to want to do that, so I dug into the layout again, and it turns out it's possible to scooch that e2p chip over just enough to get it out of the way, though it's now rather close to the clock chip and I had to put in yet another pair of vias to get the routing to work. Here's a snapshot of the relevant portion of the layout in FreePCB:

 

skunkpic-1.thumb.jpg.de01e2ceb20293b84320f5ce8b749d08.jpg

 

However, being forced to think creatively again, I managed to clean up some routing by relocating a large portion of one of my new serial EEPROM selection traces to the back of the board, and hence was able to give the clock traces a little more breathing room. One step forward, one step back for the clock signal. Hopefully it turns out OK. I also took the opportunity to tweak the silkscreen a little based on the first prototypes. Some of the labels got pretty cut up by via holes, so I moved them around a bit to make them a little easier to read on the finished boards.

 

I've been working on the software quite a bit as well. I have a 4.0.0 BIOS and associated JCP 2.0.6 ready to go now, and I've pushed them to github:

 

https://github.com/cubanismo/skunk_bios

https://github.com/cubanismo/skunk_jcp

 

I haven't posted much about these yet even though I pushed the JCP code a while ago, because I was thinking about writing a windows installer for JCP that would automatically install the necessary USB drivers too, but that is looking like a major hassle, so I'm not going to pursue it for now. Zadig is easy enough.

 

The last feature I wanted to get right in the BIOS was selecting a serial EEPROM, then flashing a game, and having the serial EEPROM selection apply when that game auto-booted after the flash. This was tricky because the flasher resets the EZHost and flash chip after a flash operation to get the flash chip out of fast write mode. Resetting the EZHost chip clobbers the GPIOs that control the serial EEPROM selection, resetting them to the default state. The selected state isn't cached anywhere in the BIOS, because it can be manipulated directly by JCP without interaction with the BIOS code. It just tells the EZHost chip to toggle the GPIOs directly. Luckily, reading the GPIO output value registers on the EZHost chip returns the last value written, so it's a "simple" matter of reading the register, resetting the EZHost, and then restoring the value. Simple in quotes because this meant implementing a second EZHost LPC operation: Control register read. The control register write routine isn't huge, but it isn't tiny either, and I was worried about bloating the BIOS out too much just to handle this one case, but in the end I managed to make the control register write routine generic enough that almost all of it could be used for the read routine as well. The read routine ends up being a 5 instruction header that then jumps into the write routine, and I think I had to add 2 additional instructions to the write routine to make it handle both cases. It's a minor thing, but it made me happy to see it work out elegantly. It could be smaller still (only two additional instructions for the read stub), but I'm paranoid and insist on clearing the mailbox before starting the routine. 3 or 4 instructions in the name of defensive coding in a piece of code that can brick the board, or at least make the serial EEPROM useless for those without access to BJL if it doesn't work isn't a bad thing IMHO.

 

Take a look at the new comments in the code for a summary of how the EZHost LPC mechanism works if you're curious. It took me a lot of research to dig up the knowledge needed to write that one little routine.

 

Note the version 4.0.0 BIOS will also work just fine on any Rev.2+ skunkboard, but there's no reason to use it except on Rev. 5 boards, so I haven't included an option to upgrade to it on older boards in the new JCP. The only benefit would be your version number saying "4", as the only new functionality is the serial EEPROM selection stuff. If that matters to you, go ahead and figure out how to force upgrade your board manually. It's not that hard. However, be warned I might key off version 4+ to add new features that only work on Rev.5+ boards in future BIOS or JCP updates, and then you'll be at risk of things going wonky if you force-flashed this on your non-Rev.5 board and then naively apply an update years from now. You've been warned!

 

The new JCP adds three options:

  1. '-k' to select (sele'k't, or 'k'hip select) an EEPROM. Requires a parameter of 0, 1, or 2, which select no serial EEPROM, the 93C46 EEPROM, and the 93C86 EEPROM respectively.
  2. '-g' to 'get'/dump the currently selected serial EEPROM's contents to a file on the host computer.  Serial EEPROM equivalent off the '-d' option.
  3. '-p' to 'put'/write the content of a file on the host computer to the currently selected serial EEPROM on the skunkboard.

To make testing the new BIOS easier, I also added the ability to dump a 6MB ROM. This utilizes existing options, but just makes them work better together: Run 'jcp -6d <filename.rom>' to dump a 6MB ROM from the skunk to a file. Why not just use regular '-d' followed by '-2d' to dump both banks and concatenate the results then chop off the last 2MB? Because -d hard-codes the first 8k to the universal ROM header rather than the actual flash content, so you'd end up with 8k of what amounts to garbage in the middle of your 6MB ROM image doing that. Again, my initial version just dropped in a nearly identical bit of code to the existing romdump stub that dumped 6MB roms instead, but I wasn't satisfied with that and rewrote it so one stub could dump both ROM sizes with a little cleverness, even though it's just JCP, not code running on the jag. Check out the code if you're curious. Such is the joy of hobby projects: You can pointlessly optimize to your heart's content without anyone yelling at you about some deadline.

 

Note the '-g' and '-p' options work on any skunkboard with a serial EEPROM (hacked boards, the ones from zaxon@sellmyretro.com, Rev.4 boards), and the 6MB dumping works on any Rev.2+ board, so most of the new JCP features aren't limited to my new boards.

 

Once I had the new BIOS and JCP finalized, I updated the test2.sh script from bjlSkunkFlash to verify the new serial EEPROM functionality on the Rev.5 boards, and also to test 6MB ROM flashing while I was at it. The latter doesn't actually verify any additional HW functionality as far as I'm aware, but I wanted to tick it off the testing list for the new BIOS and figured I'd just leave it in there. More testing never hurt anything, and I don't mind listening to Bad Apple every time I bring up a new board. Sure beats watching the AvP attract screen do its thing over and over again.

 

Not as sexy as shiny PCBs or mutilated chips, but here are a few pics of the resulting BIOS, JCP, and test script in action:

 

skunkpic-2.thumb.jpg.529f2406e56e7e39cae3037135157f7a.jpg

 

skunkpic-3.thumb.jpg.adc6820aeb331cfe57a6029160dddfa7.jpg

 

Note the auto-detection of serial EEPROM type in action ? Even if I build boards with two 93C46 chips, two 93C86 chips, or accidentally reverse which chip is in which slot, JCP will figure it out. I don't plan on doing that, but it was actually easier to write it this way in the end anyway. You can also see how ridiculously slow EEPROM writes are: 1.419 seconds to write 128 bytes - yeesh. Check out Atari's EEPROM routines to see why. The chips aren't quick, but they're not as horrible as that normally.

 

And just to get one fun picture in here, I've built up all 3 of the initial prototype boards at this point. Here's the final one, just completed:

 

skunkpic-4.thumb.jpg.8b62ebf1cd2a32b7358fead90e20263b.jpg

 

These things are great SMT soldering practice. By the 3rd one, I was able to solder all 3 of the big ICs on pretty quickly with only minor issues (I missed one short by visual inspection, and accidentally left one pin loose that I didn't notice prior to cleaning all the flux residue off. Anyone have a good no-clean flux pen to recommend?). It took me 3 hours and 10 minutes from sitting down at my desk to completely finishing the test2.sh script successfully on that last board (Don't worry, that's not wall clock time. I took breaks), and roughly 45 minutes of that was coming to the brink of desoldering the flash chip because AvP kept rebooting at the title screen and I figured the flash chip was broken after checking all the address/data pins for connectivity. While the hot air gun was warming up, I decided to try the same test on a known-good board first, and it did the same thing there. Alarmed, I plugged in my actual AvP cartridge, and it did the same thing too. For a minute, I was scared that my Jaguar was dying, but then I looked down and realized I'd left the BJL cable plugged in from when I flashed the skunkboard BIOS. Sometimes BJL seems to leave the bits it outputs on the computer's parallel port in a state that results in the Jaguar seeing a button or two being held down on the 2nd controller. I must have had the unfortunate luck of it having the equivalent of #+* held down or something. I unplugged it and the new board was good to go on its second run through test2.sh.

 

I've yet to get through a build without running into at least one annoying little issue like this that eats up a bunch of time, but each one is a lesson learned. Last time it was flux residue leaking on to the cartridge connector and making the board sort of flaky until I finally noticed it and scrubbed the connector pretty thoroughly. Now when I de-flux the boards, I hold them upside down. I should be able to build a board in just over 2 hours start to finish at this point in theory, probably faster if I build 2-3 at once to amortize setup time now that the actual build process is going more smoothly (My OCD insists I disassemble and put away my JTAG programmer every time for example, including putting all the cables back in their respective twist ties and other pieces in their anti-static bags, then putting the box back in its correct place on the shelf. Nothing worse than a messy workspace. The setup+teardown take about 5x longer than the actual programming though). I'll have three more boards when the RC2 prototypes come back in a week or so, and I think I'll build them in parallel to test that theory.

  • Like 6
  • Thanks 1
Link to comment
Share on other sites

  • 2 weeks later...

Not tested == broken

 

This is one of those "truths" that isn't and is at the same time. Is your code or hardware necessarily broken if you don't test it? No. Can you rely in it NOT being broken if you don't test it? No.

 

I mentioned before I wanted to do something to make use of the extra USB ports on skunkboards, but that I hadn't written up any of the code for it yet. It dawned on me that if I send people a bunch of skunkboards with untested USB ports soldered on them, then write some code to make use of those ports and release it, I could potentially have a bunch of people suddenly discover they have broken USB ports on their built-by-me skunkboards. That would be bad for everyone involved. So I needed some code to verify them that I could add to the test2.sh bringup testing script run on every board after it is built to verify the hardware. I'd been hoping I could put off my USB experiments, but it seemed that was wishful thinking, so I took a break from working on packaging and manuals and other polish things to dive into the USB specifications in detail. @Zerosquare cautioned against this, and he's not wrong, but I made it out alive. I now have a very, very primitive but functional USB host driver running on the Jaguar + skunkboard.

 

skunk_usb.thumb.jpg.9011949e58fae392407f31dd93cb770c.jpg

 

I didn't start from scratch. There's a file in the skunkboard full release that appears to be an attempt at a USB boot stub. There are hints in the misc. skunkboard docs that work began on this in an effort to bootstrap Linux on a USB stick plugged into the EZHost port, but interest waned. I compiled it and and started it up, but it didn't really appear to be functional. It was part way there though: The USB control message function kind of worked sometimes, and there was a mass storage command implementation that did not appear to work, but was useful in that it conveyed a design. In theory the control commands alone were enough to validate the USB circuitry was sane, but I wasn't satisfied. I wanted something that exercised the paths I actually wanted to use: Mass storage bulk reads and writes, or in English: reading and writing data on a USB flash drive. So I started poking at it, reading a section of the EZHost BIOS manual, reading a section of the USB 2.0 spec, reading a section of the USB mass storage spec, the SCSI specs (USB storage commands, like all the good storage protocols, are just encapsulated SCSI commands. Funny how SCSI more or less got it right decades ago.), the EZHost data sheet, over and over again iteratively building up an understanding of each by lining it up with the content in the others.

 

The bane of my existence through this, and most of the problems in the existing skunkboard USB sample code, had to do with one tiny detail of the spec: the data sequencing bit in USB packets. Each packet has a data sequence bit of either 0 or 1. Generally speaking, if you get two zero packets or two one packets in a row, you can assume something's gone wrong and you've just received the same packet twice, drop the latter one and tell the sender you've done so. Simple design, but the devil is in the details. For example, the packets aren't *always* sequenced that way. Control commands always start with a zero bit setup packet, regardless of the prior sequence bit value, followed by some number of data packets with the normally toggled sequence bit (1, 0, 1, 0, etc.), but then always end with a status packet with a sequence bit of one, regardless of the sequence bit value in the last data packet. Sure, OK, but it took quite a while to figure that out. Also, if something goes wrong with reception of a packet on the other side, you have to account for that by pretending the sequence bit of that packet never happened on your side when generating subsequent packets. This is all clearly spelled out in the USB spec, but that spec is also about 600 pages long, and even once you've identified the right sections, if you've ever spent much time reading technical specifications, you're aware of the difference between "clearly spelled out" and "easy to understand on the first read through." When you first pick up a new spec, you're generally constantly flipping back and forth between the one paragraph you're trying to comprehend and the glossary, other sections it references, etc. before you can even read a single sentence with comprehension. It took me probably 10 tries to get this stupid data sequence thing right in the code, and I definitely thought I'd nailed it on at least 6 of those tries only to have it fail exactly as badly as it had before. This was exacerbated by the fact that one of my USB devices is just crappy and currently requires me to put in some random sleeps in the host code to wait for it to be good and ready to accept the next command. Figured that out when deleting a debug printf caused it to just stop responding to commands. Did I mention USB devices are finicky bastards above? Oh yes, I did. Good.

 

In the end, I rewrote the mass storage command handler almost entirely, and currently have it in a state where it's very stable in my limited testing, but only sends one packet per frame, severely limiting the bandwidth. Stable is good though. This code is the foundation for all the layers that sit on top of it, so with something stable at the bottom, I could test all the bulk-only transport commands I wanted on top of it with ease. I can ask the drive what features it supports, how big it is, and read and write data to it. What else is there, right? Well plenty, but that's enough to test out the bus pretty thoroughly IMHO. I should probably try to speed it up again to stress things electrically a bit more, but this is a good start at least.

 

I ended up with two little programs:

 

One that touch-tests the driver by querying a bunch of info, dumping the hex data of the first block of the flash drive plugged into either host USB port on the skunk, writes some known data over it, reads it back and dumps that out to verify the write was successful, then restores the original data

 

Another that simply dumps the first 2MB of the flash drive (on either USB port as well) to the host computer using skunkFILEWRITE.

 

I plan to write a third that writes 2MB of data to the flash drive using skunkFILEREAD and using the raw data dumper/write pair in the test2.sh script: Write 2MB of pre-generated random data, read it back, and compare to validate the writes and reads both work. Good enough for HW validation.

 

What am I really going to do with this in the end though? Dumping chunks of data is pretty boring unless you want to just dedicate a USB drive to raw unformatted data blocks you write with "dd" on Linux or some dedicated tool, but it turns out it's a very small step to go from what I have thus far to full-blown filesystem access using FatFs. Hook up 3 functions and you're good to go for read-only access from what I can tell. 3 more for write access. That's when things get interesting. You can then easily access an arbitrary amount of data from your skunk-aware Jaguar games just by writing it to a flash drive in the file manager on your computer running any operating system, plugging the flash drive in to the USB port on the skunk, and then opening it based on the path and file name just like you would on the computer. It won't be super fast, but with some optimization, it should be able to at least get up to the speeds of the CD unit (300KB/s), and in theory USB 1.1 full speed devices (The max the EZHost chip can support, though USB 2.0/3.0 devices are backwards compatible) can do around 1MB/s after accounting for overhead. Have to optimize that transfer code I mentioned above and see what we can do!

 

For now, here's a look at what my USB driver touch-test program looks like on the host computer:

 

$ jcp -c testdrv.cof 
jcp v02.06.00 built on Oct 31 2020

COFF File:  Skip 168 bytes, base addr is $4000, length is 10016 bytes
Sending... 
Jag accepted start request at $00004000.
 
Finished in 100 millis, 100KB/second.
 
Starting console...
Starting up

Full-speed device detected on port 0
Language IDs supported:
    0x0409
    0x0000
Device Manufacturer:  HP
Device Product Name:  v115w
Device Serial Number: AA00000000000704
Found bulk interface, interface subclass: 0x06

USB1 Initialized

Peripheral Device Type: 0x00
Removable Media? yes
Vendor ID: hp      
Product ID: v115w           
Product Revision Level: 1100
Last Logical Block Address: 0x00f02fff
Block Length in Bytes: 0x00000200
Raw data from logical block 0:
00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000110: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000120: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000130: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000140: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000150: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000160: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000170: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000180: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000190: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001c0: 0200 0bb5 faff 0100 0000 ffff f0ff 0000  ................
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

Data written to logical block 0:
(Should be 0x00, 0x01, ... 0xfe, 0xff, 0x00, 0x01 ...)
00000000: 0001 0203 0405 0607 0809 0a0b 0c0d 0e0f  ................
00000010: 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f  ................
00000020: 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f   !"#$%&'()*+,-./
00000030: 3031 3233 3435 3637 3839 3a3b 3c3d 3e3f  0123456789:;<=>?
00000040: 4041 4243 4445 4647 4849 4a4b 4c4d 4e4f  @ABCDEFGHIJKLMNO
00000050: 5051 5253 5455 5657 5859 5a5b 5c5d 5e5f  PQRSTUVWXYZ[\]^_
00000060: 6061 6263 6465 6667 6869 6a6b 6c6d 6e6f  `abcdefghijklmno
00000070: 7071 7273 7475 7677 7879 7a7b 7c7d 7e7f  pqrstuvwxyz{|}~.
00000080: 8081 8283 8485 8687 8889 8a8b 8c8d 8e8f  ................
00000090: 9091 9293 9495 9697 9899 9a9b 9c9d 9e9f  ................
000000a0: a0a1 a2a3 a4a5 a6a7 a8a9 aaab acad aeaf  ................
000000b0: b0b1 b2b3 b4b5 b6b7 b8b9 babb bcbd bebf  ................
000000c0: c0c1 c2c3 c4c5 c6c7 c8c9 cacb cccd cecf  ................
000000d0: d0d1 d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf  ................
000000e0: e0e1 e2e3 e4e5 e6e7 e8e9 eaeb eced eeef  ................
000000f0: f0f1 f2f3 f4f5 f6f7 f8f9 fafb fcfd feff  ................
00000100: 0001 0203 0405 0607 0809 0a0b 0c0d 0e0f  ................
00000110: 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f  ................
00000120: 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f   !"#$%&'()*+,-./
00000130: 3031 3233 3435 3637 3839 3a3b 3c3d 3e3f  0123456789:;<=>?
00000140: 4041 4243 4445 4647 4849 4a4b 4c4d 4e4f  @ABCDEFGHIJKLMNO
00000150: 5051 5253 5455 5657 5859 5a5b 5c5d 5e5f  PQRSTUVWXYZ[\]^_
00000160: 6061 6263 6465 6667 6869 6a6b 6c6d 6e6f  `abcdefghijklmno
00000170: 7071 7273 7475 7677 7879 7a7b 7c7d 7e7f  pqrstuvwxyz{|}~.
00000180: 8081 8283 8485 8687 8889 8a8b 8c8d 8e8f  ................
00000190: 9091 9293 9495 9697 9899 9a9b 9c9d 9e9f  ................
000001a0: a0a1 a2a3 a4a5 a6a7 a8a9 aaab acad aeaf  ................
000001b0: b0b1 b2b3 b4b5 b6b7 b8b9 babb bcbd bebf  ................
000001c0: c0c1 c2c3 c4c5 c6c7 c8c9 cacb cccd cecf  ................
000001d0: d0d1 d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf  ................
000001e0: e0e1 e2e3 e4e5 e6e7 e8e9 eaeb eced eeef  ................
000001f0: f0f1 f2f3 f4f5 f6f7 f8f9 fafb fcfd feff  ................

Done!

 

And the code is available here if you're interested:

 

https://github.com/cubanismo/skunk_usb

  • Like 3
  • Thanks 2
Link to comment
Share on other sites

On 11/5/2020 at 9:57 PM, CyranoJ said:

Nice work, if it wasn't for the JagGD I'd be all out for one of these!

Exactly how I feel.  I have an old Skunk 2 that has no save feature, and always has a couple of my favourite homebrews on it.  I'd get one of these, but the GD seems to be close to release.

Link to comment
Share on other sites

2 hours ago, ls650 said:

Exactly how I feel.  I have an old Skunk 2 that has no save feature, and always has a couple of my favourite homebrews on it.  I'd get one of these, but the GD seems to be close to release.

Absolutely. If you want to play some games and want the best experience, get a game drive. It's a better product in almost every way, and I don't want to detract from the investment anyone, especially @SainTand his retail partners, have made in it. I'm doing this mostly for fun, but I knew there would be people out there who wanted one for whatever reason: as a collectible, because it'll be a little cheaper in the US, whatever. I'm still eagerly awaiting a game drive myself.

Link to comment
Share on other sites

1 hour ago, JagChris said:

Those of us who have skunkboards already, will we be able to update ours with this mass storage feature when it's ready.

If you have the two side usb ports, it should work on your board.  Not specific to my new boards. I know the Rev.3 boards shipped without the extra USB ports.  If you have those, you can just order the parts from DigiKey for a few dollars and solder them on though. It's an easy through-hole soldering job anyone could do as their first soldering project.

  • Like 1
Link to comment
Share on other sites

7 minutes ago, cubanismo said:

If you have the two side usb ports, it should work on your board.  Not specific to my new boards. I know the Rev.3 boards shipped without the extra USB ports.  If you have those, you can just order the parts from DigiKey for a few dollars and solder them on though. It's an easy through-hole soldering job anyone could do as their first soldering project.

Thank you for this confirmation and for your work. I have a Rev.3 board, and it was possible to ask for the extra USB ports to be soldered or not. I asked to have them soldered, I feel a bit lucky.

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

I got the 2nd batch of prototype boards back last week, and as planned I set about building them all up in parallel to see if that improved throughput significantly. Spoiler alert: It did. I ended up tossing in a Rev.4 board just so I could do an even 4 in parallel. I attached all the parts I use solder paste for first (U4, U7), then all the big ICs (U1, U2, U3), then all the misc. other components (capacitors, the serial EEPROMs, the USB ports, etc. The easy stuff).  Here's the four boards on-deck for final component soldering while I was doling out all the misc. components into the notches up on top of my work area for quick access:

 

skunk_proto2_1.thumb.jpg.b7e0431314d09b6f5d3454d1a70f177e.jpg

 

Those little rectangles on top of the silicon mat are all numbered, so I just put C1-C20 in slots 1-20 on the mat, R1-R2 in 21-22, L1 in 31, and the bigger stuff in those big squares on top. When I build four boards, I put four items in each slot. Great little feature I didn't appreciate until I was on my 2nd or 3rd skunk and started making use of them. Before that, I was just digging the components out of the little bags and tape packages they come in one at a time, which besides being inefficient, left my soldering iron sitting there idle, collecting oxidation unless I remembered to tin it between every component. Not a good way to work.

 

Also note the skunk graveyard up there in the middle: That's where I pile up the failed builds so I can scavenge parts off them, which I ended up doing judiciously during this build because I was short on clock and mini-USB parts, as well as a few others. Desoldering those mini USB plugs is a pain.

 

Things started out well. I was jamming, really turning through the work. Didn't even have any issues on the fragile Rev. 4 board. As I got to the last components, I completed the first board, programmed its CPLD, and started it on the bringup test script while I soldered the misc. remaining components on the next board. I found I could just about complete the soldering work in the time the test script took to run, so this seemed like a good process. Unfortunately, as I was pulling the second board off the JTAG cable, something went wrong. I don't know if I brushed the connector across the board just the wrong way as it came out and shorted something or what, but it killed the board: Ground and VCC were now bridged somewhere. I wasted a ton of time desoldering components until the short was cleared. Removing the CPLD finally cleared it. Cleaned it up and soldered it back on, the short was back. Desoldered it, it was clear again. Soldered a fresh CPLD chip on, short was back. No idea what happened here, but the board seems to be lost, and I wasted about 3 hours trying to revive it. This is the first board I've lost for unexplained reasons. I may have touched something wrong as I mentioned, but I really don't think I did. Regardless, I think a good lesson here is probably to not get too bogged down on failures like this. I should have just set it aside and moved on, maybe revisited it later if I was bored. The time invested wouldn't have been worth the cost of the lost components even if I'd fixed it, and I didn't learn anything from trying to diagnose the failure.

 

I still need to finish the last board, as I'm still short one mini-USB plug and after going through the effort of desoldering one from a failed build for the 3rd board, I decided I'd rather just wait until my next DigiKey order arrives than do that again, but all the rest of the soldering and bringup is done. Overall time was about 1 hour and 45 minutes per board, including all setup, cleanup, and bringup+testing time, assuming things go smoothly on the last board.

 

Oh, and of course this means the prototype 2 boards are functional. The layout changes also accomplished their goal:

 

skunk_proto2_4.thumb.jpg.b87e9f993b7a66e8991cdf76263b721d.jpg

 

Though it is still a *very* close fit. Don't know if others can make it out below, but the top serial EEPROM package *just* clears the support structure in the cartridge cases, to the point that I might want to be careful about placing them more towards the left than the right of their pads when soldering just to be on the safe side:

 

skunk_proto2_3.thumb.jpg.5ca4d2f3608166ded0a09b177d51107d.jpg

 

And here's a front view...

 

skunk_proto2_2.thumb.jpg.bbc6b7205f438a7748f54b32ab33cabe.jpg

 

...which shows the remaining problem if you look closely: the cool logo silkscreen didn't fare as well this time. The JTAG header labels ended up merged with the main Skunk Board graphic, and everything just looks a bit... bloated in general, even though I'm fairly certain I used an almost identical file for each. I think I know what's going on here though. The process for converting the Inkscape SVG source file I use for these to the gerber file used for manufacturing involves converting them to a KiCad component. For whatever reason, KiCad seems to insist on all its component silkscreen fill regions being outlined with a very thin stroke as well. No idea why. That stroke is thin enough that it effectively becomes either 0 or 1 pixels of whatever resolution you're working at for any practical resolution. This is visible in gerber viewers as well: When I load up the silkscreen in some viewers, it looks like it has no stroke around the graphics. In others, it looks all blotchy like it does on the 2nd prototype boards unless I zoom way in. I think on the first boards, this outline stroke got clipped to nothing, and on the second ones, it rounded up to 1. Fortunately, it's relatively easy to fix. I read up on the gerber file format a bit, and then wrote a little VIM macro that went through and deleted all the stroked paths from the gerber file. This looks much cleaner in the gerber viewers where it looked problematic before, but viewers can never fully simulate what happens at manufacturing time, so I'll have to do one more prototype build just to test the damn silkscreen. What I think I'm going to do here is quickly lay out another board I was looking to prototype in the same form factor as the skunkboard, then just slap the skunk silkscreen on the back of it. It'll be a far more trivial board that will be much cheaper to manufacture (2 layers instead of 4, no tiny VIAs like I had to use to squeeze in the EEPROM routing, no edge connector), and I'll get to test more than just the graphic, so I won't be as upset over the wastefulness. I have that board layout about 33% complete. Just need another free evening or two to polish it off.

 

However, right now, I'm hobbying remotely, as we headed up to my parent's for the Thanksgiving holiday last weekend. I don't know if I'll go through the trouble of getting FreePCB up and running on my laptop to finish my layout while here, but I didn't want to give up working on the Jaguar entirely, especially given everyone else here is in bed by 8:30pm and I'm more of a night person, so I made preparations. I already access my skunkboard remotely even while I'm home. It's plugged into an always-on Rasberry-Pi-form-factor board that I ssh into or use my rjcp script to target. I also have most of my computers plugged into one of those "smart" power strips I picked up for nearly nothing last year on PRIME day, so I can toggle them on/off from the world's worst app on my phone (Hey, it's functional). Luckily, the Jaguar has an old-school physically-activated power switch (Why are soft power buttons considered an advance? So much worse.), so before I left, I rigged my Jaguar up to a plug on that so I could power it up at night to work on it, power-cycle it if I borked things so bad that jcp -r didn't bring it back (This happens more often than I'd like to admit), and stuck a USB drive in it so I could work on my USB code, which I did last night. Here's the whole mess:

 

remote_skunk_1.thumb.jpg.c12b95d9d343d51198f91b2ef60a759d.jpg

 

remote_skunk_2.thumb.jpg.b5f6404f5fe4315e22f23d44b633ea7c.jpg

 

remote_skunk_3.thumb.jpg.0bea19ddb6646852cf4acba5f2b6f335.jpg

 

I've started refactoring the USB code to look more like a real USB driver, building a software USB transaction data structure I can serialize and submit to the EZHost hardware on the fly, and then deserialize from the EZHost structures when it reports status back, and pump the whole queue/recover from errors/resubmit as needed without all the weird semi-stateful retry loop hacks and hard-coded memory locations in the current code. I haven't gotten that far on this yet, but the end result should be much faster USB throughput and better error recovery/handling.

  • Like 5
Link to comment
Share on other sites

On 11/25/2020 at 6:46 AM, cubanismo said:

Ground and VCC were now bridged somewhere. I wasted a ton of time desoldering components until the short was cleared. Removing the CPLD finally cleared it. Cleaned it up and soldered it back on, the short was back. Desoldered it, it was clear again. Soldered a fresh CPLD chip on, short was back. No idea what happened here, but the board seems to be lost, and I wasted about 3 hours trying to revive it. This is the first board I've lost for unexplained reasons. I may have touched something wrong as I mentioned, but I really don't think I did.

Does your PCB manufacturer offers electrical testing? If not, a possible cause is a defective PCB with an intermittent short between close pads or inner layers.

  • Like 1
Link to comment
Share on other sites

10 hours ago, Zerosquare said:

Does your PCB manufacturer offers electrical testing? If not, a possible cause is a defective PCB with an intermittent short between close pads or inner layers.

Yeah, that's very much what it seems like. 

Manufacturer was Osh Park, same as the last round, who in turn contract the actual fabrication. It's not clear to me from their website what testing they do, if any.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...