Friday, May 27, 2011

Apricot cards arrive...

Yay, another new board in the mail... This time it's the apricot card for the alpha backplane.  I used Laen's service (DorkbotPDX) so I got 3 copies of the design.   Quick electrical tests (resistance between linked pins and unlinked pins) look correct.  I did make a stupid mistake with the hole sizes for the sma connectors (I really should just always make my own components every time). This card contains the usual msp430 board controller for the alpha series backplane, but also a tiny happy fpga (Xilinx spartan 3AN) so I can begin exploring signals (bound to all the single ended and differential lines).  There are multiple additional power supplies here that are controlled by msp430 (the microchip MCP1825 for 2v5 is in the upper right)

On the backside is the 1v2 core ldo and the rest of the power routing to the fpga - decoupling caps for the core and io banks take up the middle region.  Off the left is the microchip MCP1826 regulator for 3v3 (much higher current and controlled by the msp430).

The copper layer is excellent and the solder mask is almost as good (spoiled I am by whoever fabs these boards - always say it because it's always true). 

No copper errors on any of the 3 boards, no anomalies in the thickness or placement, no bleeds from the copper fills, holes are easily within spec for position and size.  The silkscreen is a much lower resolution but easily legible enough on the tiniest letters for assisting placement.

I can never really tell with vias in fill zones whether they are plated through - they always seem to work - I always get that moment of fear that they aren't because it's so easy to see the plating on the larger holes with annulars... with some manufacturers I can see a raised bump from the vias in fill regions, this one is just flat.  I also like the fact that the mask doesn't randomly fill the vias (I really don't like to see that).

I left out the sma connectors (because I botched the hole sizes in the design) but the rest of the components are in... yay...  One the bottom is the DIN 41612 connector (This one is Molex - it doesn't have the retention clips but surprisingly it stayed perfectly in place when soldering because of the card edge tension... nice when parts hit spec).   Just above that are the differential termination resistors (I'm starting with them at 150 ohms but this will likely change as testing begins - the alpha backplane is 2 layers with intended characteristic impedance targets for the signal lines between 148 and 152 ohms, differentials closer to 180 (these are far from the ground plane and tightly coupled).  I'm not certain what the actual imp. will be or how much it will change depending on slot population (which is what testing ought to reveal) but eventually after I get some real world data the act/dyn impedance control designs can begin... Single ended lines are not terminated on this card.

On the bottom right is the little ldo (3v3 always enabled) for the msp430 controller - I like to use the micrel MIC5205's for this - low noise, easy, simple, always works.  Above that is a small ceramic filter cap and a standard resistor/led combo (I don't usually put leds on all the power supplies but when there isn't an enable control for them I do - saves trouble shooting and drains the caps once the power is cut).  This 3v3 supply feeds the msp430 controller just above (socket is empty here) and fills the electrolytic cap on the top (but backside) of the board.  Above the controller socket are the filter caps and the pullup resistor for reset (needed by the sbw programmer - just tap a launchpad - works great and cheap).

In the center is the Xilinx Spartan 3AN fpga (just a tiny one - but enough for this).  Near by are the split jtag interface and a jumper for PUCD.   This fpga has an internal flash so I don't have to add a separate prom image - yay.  There are four io banks, 1 is locked to 3v3 (backplane SPI/I2C is 3v3) but the others are switchable (jumpers on the left side).  Some pins are brought out for external use on the top as well as 2 sma connectors (but remember I botched the hole sizes so they are left unpopulated).  The 2v5 regulator is on the lower left side as well as it's filter and bulk caps. 

On the back side we find the 3v3 regulator for io banks (controlled by the msp430) in the upper right side and the bulk caps for the 2v5 and 3v3 bank io supplies.  The center has the filter cap arrays (4 banks and logic) and the 1v2 core logic ldo with a 100 uf Tantalum cap).   In the upper left is the 50 MHz oscillator.  I haven't washed the board yet so the flux around the DIN 41612 connector is visible around the pins.

Here's we have the apricot and the niblet termination boards on the alpha backplane... yay signal testing soon...

Thursday, May 26, 2011

Niblet cards arrive...

Always great to get new boards in the mail... This time it's the niblet cards for the alpha backplane.  I used Laen's service (DorkbotPDX) so I got 3 copies of the design.   Quick electrical tests (resistance between linked pins and unlinked pins) look correct.  This card contains the msp430 board controller and provides termination points for the single ended and differential data lines.  It also provides access to the backplane I2C bus as well as the SPI bus and plenty of access points to breakout the signal and power lines for prototype access.



For the single ended lines there are spaces to add pullup or pulldown resistors (or to couple to ground with a cap if needed).  I put the bulk cap for the 3v3 suppl on the back, but otherwise not many components here...

As usual, the copper layer is excellent and the solder mask is almost as good (spoiled I am by whoever fabs these boards).  No errors on any of the 3 boards, no anomalies in the thickness or placement, no bleeds from the copper fills, holes are easily within spec for position and size.

I have no idea what the actual production limits are but the accuracy and precision is clearly much better than the limits we have to make (which is a very good thing).

On the bottom is the DIN 41612 connector for the backplane (this one is from TE) - the retention clips are nice to have - fit perfectly (never know with a part whether it will really hit the states specs until you do it).  Just above that are the differential termination resistors (I'm starting with them at 150 ohms but this will likely change as testing begins - the alpha backplane is 2 layers with intended characteristic impedance targets for the signal lines between 148 and 152 ohms, differentials closer to 180 (these are far from the ground plane and tightly coupled).  I'm not certain what the actual imp. will be or how much it will change depending on slot population (which is what testing ought to reveal) but eventually after I get some real world data the act/dyn impedance control designs can begin...

On the bottom right is the little ldo (3v3 always enabled) for the msp430 controller - I like to use the micrel MIC5205's for this - low noise, easy, simple, always works.  Above that is a small ceramic filter cap and a standard resistor/led combo (I don't usually put leds on all the power supplies but when there isn't an enable control for them I do - saves trouble shooting and drains the caps once the power is cut).  This 3v3 supply feeds the msp430 controller just above (socket is empty here) and fills the electrolytic cap on the top (but backside) of the board.  Above the controller socket are the filter caps and the pullup resistor for reset (needed by the sbw programmer - just tap a launchpad - works great and cheap).

I didn't populate the pads for the single ended lines yet (because the may end up in many different configurations).  I also left most of the breakout headers for the power supplies and signal lines unfilled.

Now that the termination board is ready I just have to built the apricot board and fun with signal testing can begin...

Wednesday, May 25, 2011

Mistake->Frustraion->Worse Mistake... (ugh)

Happily assembling new boards - great traces, electrical tests correct, components set out in order, in the "right mood"... I found that on a new component I made a mistake with the hole diameters...

This happens (it was the one I didn't check and used a library part -> sma connector)... I had multiple other new parts (that I did make components for) and they were correct (so I was happy) and I decided to assemble anyway...

Why after I had all the smd components in place (double sided - worked perfectly - yay) I thought "Oh, I can just increase the hole sizes a bit" was a wise thing to do I have no idea.  It was a stupid stupid thing to do (for this stage in the prototype I don't even need to have the connectors to test)... But I did it anyway... dumb dumb dumb...

Of course that blew out the plating through the hole, but stupidly I thought - "that's ok since I can just solder the legs on both sides of the board".  Nope - so many problems with that on an sma connector (on a some components it works fine, not on sma connectors (no access to the center signal pin and the signal line in on the front).

After trying a number of methods to fix it I finally realized that the best thing to do would be to look at it as a learning experience... I did improve my 0603 skills (tqfp144 was unexpectedly easy) but what I had to learn (again) yesterday was apparently (Don't do something stupid trying to fix a little mistake and end up making the problem much much worse - walk away).  I knew in my gut that I should have just left the connectors off rather than risking ruining the board, but I did it anyway...

Every so often (1 or 2 times a year) I end up doing this (making a problem worse trying to fix it) and I always have that gut feeling that I shouldn't do it... Why I still do I have no idea (I do always end up learning something from it though).  The next day (after sleeping) I always have this complex mixture of happiness/understanding/contentment/embarrassment/experience, but at least the frustration is gone...

So this little board now goes into the salvage bin for parts... Hopefully today I will just do it right...

Thursday, May 19, 2011

Happy mail... (DP free pcb drawer - cpld breakout)

Yay... I received another free pcb from Dangerous Prototypes pcb drawer (I got another code for building the first free pcb... neat).  If came taped to the inside of the envelope with a business card - as before, no problems in transport at all.


Overall the board has good quality traces and pads - no bridges - electrically everything looks good - yay...

 Most of the vias were filled with the solder mask - not a problem though...

Overall the accuracy of the mask and the drill holes was a  bit better than the prototype busblaster board from before, easily in spec...

So now that I knew the board was good, I collected the components and since I was reflowing some other boards I decided to do the smd components with solder paste as well... Almost everything went well but my hand jiggled setting paste on part of the board and I didn't want to wipe everything off... This is what it looks like when you get paste a little too far away to find a comfortable place to bind when hot... The little solder schmutz is easy to remove with IPA in a syringe and/or a hot iron tip.  Always look at the board after thoguh because these things can move around, cause shorts and in general make life unexpectedly frustrating if you don't clean them up.

This is what it looks like after the components are placed.  I bumped the Tantalum caps up to 4.7 uF from 3.3 uF because that's what I had on hand.  When I first added power it passed the smoke test, but it didn't work... two minutes of testing revealed that the 3v3 ldo was working fine but the 1v8 ldo wasn't putting anything out - rechecked the lines - no shorts... The problem was that I used a 1v8 ldo from TI (TPS78918) that has an active low enable instead of active high enable... because of the routing I couldn't just cut a trace so I removed the chip - removed the trace from 3v3 to the input and enable on the 1v8 ldo completely - soldered the chip back - bridged the enable to the ground of the 1v8 ldo - soldered a wire from the 3v3 output cap to the 1v8 input... now it worked... yay.

Voltages are right and the coolrunner II is visible by jtag (side note - the 68 ohm inline resistors on the busblaster seem to work nicely).  I didn't have much time to build something to test all the io lines but they ought to be correct.

Overall it's a nice little board - easy to build and the layout is nice.  There are two jumpers to set the voltages for the io banks on the cpld (1v8 or 3v3 - the onboard supplies).  You can also tap the center post of these to supply a different voltage (I use 2v5 often) if needed.  The only problem with the design here is that the only caps between the Vccio inputs of the cpld and these pins are 0.1 uf caps... Most of the time that's not a problem with the onboard supplies since they have reserve caps but using a long wire to connect a different bank supply is going to be noisy...

So, for what it's worth these are the two suggestions if there is a new revision of the board:

First, instead of connecting the enable lines of the ldo's to their supply voltage I would consider routing them to the back of the board (easy via space available) and put two solder joints (like there is on the optional crystal) to either bind the enable to the supply voltage or ground.  This would make it easier to use ldo's with either high or low enable lines - flexibility in sourcing is good.

Second, I would consider adding pads for at least two caps between each of the Vccio bank lines and the jumpers - probably one for a small Tantalum (3.3 to 10 uF ish) and one (two would be better) for additional ceramics (depending on what you want to do with the board 1 to 10 uF).  I think this could fit on the back.   Since the 1v8 ldo is fed from the 3v3 ldo (which has a Tantalum cap on the output),  I think the cap on the 1v8 input isn't really needed... Perhaps, if this one were routed instead to one of the Vccio banks then there is still enough space on the front to add another one by the jumper for the other Vccio bank... then finding space for the other additional filter caps is easier.

Again, just my suggestions (for what they are worth) if there is another revision in the works... It's a nice little board as it is now...

Here and here are a good pages about the board (design and lots of information).  This is one of those tools that's always good to have around...

Tuesday, May 17, 2011

Sometimes a skeleton...

Sometimes it's good to look at the skeleton of an idea... adding the flesh (the substance we normally see) is the fun part, but if the foundation isn't good... well, problems happen later...

On the alpha backplane I am using I2C to control the power enable, device enable and reset states of the cards.

I'm putting up two incomplete/untested code sets: one for the msp430 controllers on the cards here and one for the pic18LF26K22 backplane controller here.  Neither is finished, but they are highly linked in function and yet quite different.

For the card controller I decided to use one large file with a choice of multiple defines in the beginning to have the small amounts of unique code to each card complied as needed.  Internally the I2C interface is handled through the msp's interrupt with a rather classic state machine handler - and unlike almost everything I do... I used global variables (it actually makes more sense to use them here for the code size and limited complexity).  Internally the cards keep track of the intended state (passed from the master controller) and the current state and just adjust in whatever unique way is needed for that card to get to where they need to be...

For the backplane controller I decided to put all the card data into a structure and pass it through pointers to the necessary functions.  I haven't written the I2C code for this one yet (or the fun "fleshy" serial monitor interface, spi inter card message passer and resource handlers).  I did write the scan code for the special I2C setup logic. 

The cards usually use the I2C interface for handling only the power enable/disable and run enable/disable signals from the backplane controller, I decided to have each one start with the same address (usually not a good thing on an I2C bus).  What happens here is that when the backplane is idle (MSTEN is low), each card will respond the the same initial address (0xD0) if the ENx line is high (same as the spi enable line) -> if the master writes to it, then that byte sent will become the new I2C address for the card.  This way the controller also "knows" exactly where each card is by the I2C address.  If a single card is hotplugged it can be handled in flight but multiple cards would need to be done with the bus idle (which ought to be idle anyway when changing cards).


Time is at a premium in the spring but I'll update the code when I get the cards built and I can test them correctly.

Wednesday, May 11, 2011

Happy mail... (DP free pcb drawer - bus blaster)

Something nice about getting things in the mail... When I opened this letter I found that I had received my free pcb from Dangerous Prototypes pcb drawer (I got a code and used it to ask for a bus blaster pcb).  If came taped to the inside of the envelope with a business card - no problems in transport at all.


Overall the board has good quality traces and pads.  It's always interesting to see the differences in the ways people make routing decisions.  Things got interesting when I was checking the traces against the schematics and started finding mystery pads on the pcb... (mysteries are fun).  It's not unusual to put current limiting resistors to protect against shorts (or bad designs)... (I confirmed this with an email to Ian - it's actually a newer prototype than the board I was expecting - cool)  I was originally thinking of 20-30ish ohms but since I don't use resistor arrays often I don't have any on hand...  Rather than having to wait for them to arrive, I scavenged some from an old graphics card with fire (Yes I did it safely in a chemical hood with a gas burner...)  I ended up selecting 68 ohms for these.

One section appeared to have a bad trace (there was an intentional cut between two pads).  Near this region I found some other bridges and trace anomalies nearby...

Those were easy to clean up... (always always always check the pcbs before you assemble - even if they pass electrical tests it's worth taking a little time up front than a lot of time later).

This is what it looks like after populating the components... (Yay it passed the smoke test) I made a couple of changes (I bumped one Tantalum cap up a little bit in size because of what I had on hand, I only have 0603 caps so I used them instead of 0805's, I used a different usb connector than the original design because that's what I had on hand, and I rigged a different type of 12 MHz crystal because again... that's what I had on hand).  Not the most beautiful soldering job on my part...

I also left out the diode for the target voltage connection... Usually if I have to connect to a device with higher voltages than the jtag programmer can handle I inline a zener on the flylead, or I make a voltage translator so that I can connect directly to a lower voltage port.  It's probably a good idea to put a zener on the programmer to prevent accidental damage, but I didn't have one so I just left it out.

I was expecting to use a different jtag programmer to setup the board, but since the chip they used (FTDI2232) has multiple ports it wasn't needed.  The documentation for the bus blaster is around here and from that there is an nice explanation of how to self program the device here. 

I also found this page in particular to be very helpful...  They to do a functional jtag test against a logic sniffer (also Dangerous Prototypes... and also something I have on hand (on the top here) - very very useful - small simple quick and dirty and efficient tool - I highly recommend it).  Chain scan worked perfectly the first time... yay...  I'll test it more completely when I get some time later, but if it passes these tests then it ought to work without problems.  I'll check the signal quality on a scope later but 68 ohms seems to be fine for the new part of the design.


Dangerous Prototypes makes the neatest stuff, and I love the openness of their development... hopefully one day I will have something worthy to contribute...

Monday, May 9, 2011

Tf-card-alpha-apricot...

In order to play around with and test signal transmission across the backplane I need a means to inject and detect signals... and so the apricot card was designed.

Like all the alpha series cards, on the left side is the din 41612 connector that binds the power and signal lines to the backplane and one the bottom is the msp430 controller.  The controller is linked to a common i2c bus and has it's own 3v3 ldo.  The controller handles the enable lines for the other power supplies and other components on the board.

One the top are the larger power supplies for the fpga (2v5 and 3v3).  Their output is connected to elecrolytic caps to buffer larger current fluctuations.  Bank 0 on the fpga is locked to 3v3 but banks 1,2 and 3 can be set to either 2v5 or 3v3 with jumpers.

One the right side two sma-rp connectors are connected to the fpga on separate banks.  These can be used to bring signals in or out over a 50 ohm line.   There are also 6 signal lines on a sip breakout.

The fpga I chose here was a spartan-3an (144 tqfp, 50Kgates) to bind both the dingle ended and differential signal lines from the bus.  It's small for an fpga, but the primary purpose here is to inject and receive signals from the bus for testing.  Having the flash on the chip makes it easier to route (hard enough to route this on 2 layers as it is - 4 would have been a lot easier).  Bringing the jtag lines out provides a means to program it and connecting the configuration lines to the msp430 controller provides a means to restart or disable it on demand.  A separate jumper is used to lock it in program mode when needed.  The fpga is also diectly connected to the spi bus run bu the backplane controller.

The top copper layer contains a few cutouts in the fill layer to prevent encroachment of the ground on the differential pairs... Most of them could be routed as I prefer but a few had to be compromised but having a signal line run close to one of the pairs or routing a pair through vias... It will be interesting to see how much this actually matters in reality.

The bottom copper layer handles far fewer signals (mostly power).  The 50 MHz oscillator is mounted near the bottom and crosses tangent to the signal lines it must.  The bottom also contains the 1v2 ldo for the fpga and the decoupling networks for the io banks.

The organizational layout is easier to see looking at the silkscreens - this is the top...

and this is the bottom silkscreen.  The 2v5 ldo runs off the 3v3 - both have nice electrolytics as buffers.  The 1v2 uses a tantalum instead right nest to the rest of the decoupling network.  The values of these caps I may adjust after I see the noise quality of the power line.

Well, that's the quick overview... the boards are sent out so hopefully soon I can put one together and have some fun...  The only other comment I want to make it that the last thing I like to do when the layout and routing is finished is to use thin lines to trace out the ground paths across the board... One of the hardest things to troubleshoot later is having a ground connection that ended up insufficient on a component... usually only appears as unpredictable intermittent errors when under load (either currect or rf/switching).

As usual, the schematics and board files and gerbers are here,

Sunday, May 8, 2011

Populating the backplane...

I finally set aside the time to add the components to the backplane (it's better if one is in the right mood when there are so many solder points).  The 5 din 41612 connectors provide power/gnd to the attached cards as well as a bus of 21 differential pairs and 20 single ended lines.  There is no termination on the backplane itself.  One the top is a microcontroller (Microchip pic 18F64K22) that connects to some of the single ended bus lines (for i2c and spi and msten), a single unique line to each connector (for spi select and i2c configuration remapping) and a series of indicator leds for status information and a low voltage serial interface for debugging.  I haven't used this particular one before but it should be ideal for this board.

The status connector can be left unpopulated (or the led array removed) to provide access to the status signal lines for testing purposes.  I here I am using larger current limiting resistors than I could because I don't need them to be very bright and I don't want to draw much current (I want aorund 1 mA).  They could be changed to lower values if you want. 

There is a little variation with the offset 40 mil holes but easily within spec and not a problem at all.   Plating through the holes is very uniform.

Looking at the bus lines (6 mil) (yes every single line to every single point) the alignment uniformity is excellent - the copper layer is the most critical... slight alignment shifts on the solder masks are no problem at all as long as the copper is right.  (Ignore the dust here - I was handling the boards a lot testing the electrical connections).

We all have our checklists and sequences for putting things together - (collect and sort the components first, start with the smallest components first, check the fit, clean the boards... an so on).  Because I have keyed connectors here I decided to mark the first pins on all the din connectors first (it would not be fun to find out 1 was in the wrong orientation later).

I have connectors from several companies and they should all interconnect - (I still like to try them all anyway).   On this board I put holes for the retention clips (they make it much easier to keep the connector in place until everything is soldered and add an additional bit of support).   Since I didn't have enough on hand I also used a version that doesn't have the clips.  Interestingly, while the upper part of the connectors are equally compatible with the male connectors, the bottoms are setup a bit differently.  The ones without the retaining clips were slightly easier to solder (I don't know why though).

The order I put it together was, clean twice with IPA on a lint free cloth -> after the smd components were finished -> I then did the din connectors -> followed by the sockets for the controller, power and status indicators -> them the single row connectors -> then cleaned the flux off the board with warm water and a soft toothbrush -> then flick almost dry -> check that the components are still all attached (yay they were) -> clean with IPA and a different soft toothbrush -> flick dry -> IPA on a lint free cloth to make certain residual flux is gone ->add electrolytic caps -> add a couple of batteries to check the 3v3 ldo (that's the happy green led here) -> add the controller chip and indicators -> done.

If all the boards come out this well I will be very happy... (two more boards to come before I can really start signal testing - the controller code will be posted when I get it finished).  The design for this one can be found here.

Tuesday, May 3, 2011

Backplanes in the mail...

Yay, when I got home last night the alpha series backplanes came int he mail (always a happy thing to get new boards).  This design pushes the manufacturing a bit so I was interested to see how things come out (planning and math never match a real object exactly).  These boards provide power (two larger supplies and 1 tiny battery supply) to a set of 5 connectors, they contain a processor to control the activation state of the attached cards (with status indicators optional) and link single ended and differential pairs between the attached cards. 

I put silkscreens on both sides (this one is technically the top layer but it's not the one the connectors and components go on).  This makes it easier to access for testing since the boards will occupy the other side and restrict access.

One of the not fun things about boards like this (with many connection points) is testing it to make certain the connections are all as intended.  It's worth spending a few hours doing it though since it is very hard to locate and diagnose problems after the boards are populated.

So after dinner I sat down and tested... All the ground connections are correct (connected to each other and not connected to the supply lines).  All the supply lines (1,2 and 3) are correctly connected to each point they ought to be and not cross connected to each other. (yay)

Some of the single ended lines on the cards are connected to the controller individually and those are correct.  Some of them are connected to each other as a bus as well as the controller and those are correct (no cross connections to gnd or power as well).

The signal lines that form the buses between cards are all connected correctly to each other and there are no cross connections to the gnd or supply lines or to their neighbors (this was tedious to test and I kept loosing my place so I started using masking tape to mark my positions after a while).

I also measured the resistance between connectors for the signal lines.  With the limited equipment at hand it always came out as 0.1 ohms for one connector distance (which is 1.5 inches), 0.2 ohms for two connectors, 0.3 ohms (fluttry with 0.4 ohms) for 3 connectors and 0.5 ohms for 4 connector distances (which is 6 inches).  Clearly I'm too close to the limit of the meter I was using, but it looks like about 1 ohm per foot (give or take).  If I chain signal lines to increase the distance it look more like 1.3 ohms per foot (linking 6 sets of 6 inches for 3 feet at 3.9 ohms).  This would translate to 0.16 ohms between the connectors (1.5 inches).  I guess this makes sense for 6 mil lines.

I also did some quick capacitance tests (low frequency, not high yet) and it seems that looking at the power connectors it's: 149pF between supply1 and gnd, 70pF between supply2 and gnd, 13pF between supply3 and gnd, 31pF between supply1 and supply2, 13pF between supply1 and supply3 and 9pF between supply2 ad supply3.  Since capacitance can change so much depending on the environmental conditions in this case, the absolute numbers are not as interesting as the relationships between them. (I subtracted the air distance only measurement so that these are just the effects due to the board itself.

I was kind of surprised at the uniformity of the capacitance of the signal lines.  The single ended lines that had connections to the controller all ranged from 17 to 23pF depending on the connector to gnd.  All of the individual lines connected only as a bus were 22pF to gnd.  All of the signal lines were 18pF to supply1, 15pF to supply2 and 8pF to supply3.  Column A always has singles ended lines and columns B and C form a differential pair.  For the rows with signal lines the cap. between A and B or A and C was always 6pF and between B and C it was always 10pF (making me suspect that the closeness of some of the lines around the connector pines plays a large role here).

Measuring the cap. from the supply and ground lines on the connectors gave about the same numbers as measures from the power connectors but varied up or down 1 or 2 pF depending on the individual pin and the connector position.  Again, these are more for my amusement and interest rather than stating hard results since I'm doing this in an uncontrolled environment with uncalibrated equipment - but the relative associations ought to be the same).


As with the previous board from Laen's service (DorkbotPDX), the copper layer seems far more accurate than the mask and the silkscreen has the lowest resolution and variability (this is as it should be).  The smallest lettering is easily sufficient for assembling the tiny parts.  I'll get it on a scope and look closely at the traces but electrically everything seems correct so I don't expect to find anything wrong at all.  I did notice that the alignment of the solder mask makes some of the holes not to appear as centered as they really are - I could increase the size of the unmasked areas, but then that would increase the chances of an unwanted solder connection.  It's more obvious (mask intrusion) where I did fills and cutouts of the planes - it all looks good though and it's better to have more area masked than not enough (especially with tiny traces running between the holes).

I'm quite happy with the quality and hopefully I can get a board populated so I can start injecting signals soon.