kmod's blog


Working on an ARM board

Pretty much all the electronics projects I've done so far have used AVR ATmega chips as the central microcontrollers.  I've been meaning for a while to step-up into the world of ARM chips: it looks like you can get chips that are much more capable at just around the same price as an ATmega328P, but you can also get chips that are vastly more capable at slightly higher prices.

The problem I'm running into is that the ARM world is way more fragmented than the 8-bit microcontroller world, since ARM's business model is to license out their IP.  So choosing a chip isn't just a question of choosing a processor core and performance tier, but also more-or-less investing in learning a specific company's chips and toolchains.

There are a couple prominent lines out there; in the "AVR replacement" range, it seems like the two ARM processor types to consider are the Cortex-M0+ and the Cortex-M4.  The M0+ is, as suggested by the name, the lower end of the two, so I'm mostly restricting myself to looking at M4's.  Within that category, there are still a lot:

And maybe more.  Looking around at other hobbyist-type projects, the only ones I'm seeing pop up are the STM32 and the Kinetis lines.  STM32 probably wins by raw count of number of times I've seen it.  Kinetis has the potential advantage that Freescale makes the only hobbyist-available Cortex-A9 chips, ie that have a fast 1GHz+ core like in your phone.  I'm not sure if that's enough reason to choose their lower line of offerings, but it at least signals to me that they're more invested in the DIY crowd.  I've scanned through the datasheets for both the Kinetis and the STM32 and they both seem pretty reasonable; they both have a similar number of Google search results.

The development boards for these things are surprisingly cheap: $18 and $10 for the Kinetis and STM32, respectively.  I bought both of them and I'll try to play around with them; if anyone has an experience with this or an opinion either way, I'd love to hear it!


Battery-backup with in-circuit recharging

I have a pretty simple-sounding circuit I want to build, but am surprisingly having quite a bit of difficulty finding any guidance about it on the internet (maybe I haven't found the right google term?).  It's this: I want to provide a battery backup to a system, so that it can seamlessly switch between being plugged in and not.  When plugged in, though, the battery should recharge.  This is how any portable consumer device works, but surprisingly not how people seem to use batteries in the DIY space.  So the question is, how exactly do you make the system switch between the battery and the charging-source?

The simplest, most straightforward way is to set up your charging circuit and then connect the load directly across the battery, like this:


When running on battery power, the battery will just feed the load; and when plugged in, the charger circuit should split its power between the load and recharging the battery.  And if the load draws more than the recharger can provide, the battery should make up the difference.  Maybe you should add a diode so that the battery voltage doesn't back-flow into the charger IC, but you get the idea.

But the question is, is this safe?  It seems to me like it should be, but with lithium batteries I don't want to take anything for granted.  Surprisingly, I haven't found any sources online saying whether it is or isn't.  There are plenty of people who offer complicated schematics, and I can come up with explanations for why they might be better, but I haven't seen any explanations of why the easier option isn't sufficient.  One reason the complicated options are better is, for example, is if you connect the input voltage directly across the load (and use a transistor to control whether the battery is connected to the load), this lets you use the full capacity of the charger for the battery, while still powering the load (in the simpler design, the charge current is split between the battery and the load, increasing charge times).  This doesn't seem like a huge drawback for my use case, though, since recharging time isn't the most critical.

Maybe there is some issue that the charger will preferentially charge the battery instead of powering the load, though my feeling is that since the frontend of the load will be a voltage regulator, the regulator will try to make that not happen; in other words, the regulator should provide a much lower-impedance path than the battery (assuming the load is under-powered) which will take the vast majority of the current.

Anyway, if anyone knows more about whether this is done or not, please let me know, since I'm about to build a circuit like this!


Update: well, I don't really have any more answers, but one thing I think I've decided for myself is that I want to build an undervoltage-lockout circuit, which shuts off the power from the battery when the voltage gets too low.  This is for the safety of the battery, since it will over-discharge itself, which is bad for the battery, and who knows it's probably unsafe too.  Since I'm planning on having circuitry to disconnect the battery from the load in this situation, it seems like it won't be too difficult to update the "turn off" condition to also include "or if the USB adapter is plugged in".

Update #2 (4/12/14): actually it looks like maybe the approach in this post -- directly connecting the battery and load -- may be appropriate, though I'm not sure how under-voltage lockout is supposed to work.  I'm leaning this way since I just saw that SparkFun released a battery charger board that works exactly like this -- you can see here in the schematics that the battery and load are directly connected, and this is also what's suggested in the datasheet for the charger that they're using.  I'm not any closer to actually having a need for having battery backup for my project, but it's still cool to think about.

Filed under: electronics No Comments

Some design mistake stories

I spent all yesterday dealing with some mistakes I had made in some boards; I thought I'd blog about it because 1) I spent time on it and want to feel like something came out of it :P, and 2) because I think it might be interesting to someone.  Personally I find it very interesting to read about things that go wrong, since I think that that can give a better idea of how to accomplish something than just seeing a success story.  When I first started out making circuit boards I had a vague idea of what kinds of things are important, but had no idea what that meant I should actually worry about, so as a result I ended up worrying about everything!  Now, I'm starting to develop a sense of what types of things I tend to regret about my designs and I'm gradually getting more focused, but I definitely have a ways to go.

This post is about two specific circuit boards that I made multiple mistakes on, but I thought it'd be worth mentioning what things I normally don't like about my boards.  The most common thing I run into is not knowing how to "design for manufacturability" (DFM); on every single board I find myself thinking that the board is obnoxiously hard to validate once it's assembled.  Typically this means that I don't have test pads or labels for signals that end up being important; I've learned to always break out and label power nets, but I still find myself trying to touch my scope to the specific pin of a TSSOP part (the hardest part is looking at the screen while not shorting that pin to an adjacent one!).  This is pretty clearly a balancing act; I could break out every single signal, or go back to through-hole parts, but at a cost to circuit bulkiness.  One thing that I've found quite helpful is to expand the pads for almost all of the footprints I use, since the extra board space is negligible (it would usually be part of a route-out), and it helps a lot with hand-soldering or hand-testing.  Anyway, these kinds of DFM things are probably what I think about the most now during the layout part of the design.

The second thing I end up running into is that after I have the board built, I wish that it worked differently or had additional features.  Sometimes this can be addressed by leaving do-not-populate parts on the board, though at my typical quantity of 1 assembled board per design, I tend to just cut traces and green-wire when necessary.  The second part -- wanting the design to have more features or be different in some other way -- I view as a natural part of any engineering process so I don't feel too bad when it comes up, but trying to make the board "feature-complete" is what I think about the most during the schematic part of the design.

Maybe interesting to know is what I don't worry about that much: I've never put too much thought into the routing of signals or power/ground nets (other than wanting to do it easily).  As I've learned more about "grounding best practices", I've realized how far I am from them in all my board designs, but it hasn't seemed to affected any of them so far.  This is probably due to the fairly small+simplistic designs plus the low max speeds (16MHz), but so far I've been able to avoid worrying about those kinds of things.  That said, having good grounding (right now in the form of having *sufficient* grounding) is starting come up, and I suspect that these types of things will only be more important as I work my way into faster circuits.

Anyway, this was supposed to be a post about some mistakes I made; I don't consider the things I just mentioned to be "mistakes" since they're just things that I'll have to continually improve on.  I've started to rush my board-design process, to both decrease the time I spend on it but also force myself to make some mistakes to see what they are, and here's what's come up:

Barely-salvaged: power distribution board

I'll talk about the setup more later, but I've changed my designs so that instead of each board having its own power input and regulation, I have some dedicated power distribution boards so that I only have to design + build that circuitry once.  All good in theory, but this board has the privilege of being the first of mine to catch fire:

Power board, post-fire.

Power board, post-fire.

The fire wasn't really a mistake in the circuit board design, but more in my usage of the board.  That large beige connector in the top-left is a 6-pin molex connector, of the kind that you might find inside your computer.  I put this on there because I have an extra ATX power supply lying around and I thought this would be an easy way to get lots of DC power.  So after I assembled the board, I plugged in the power supply and POOF a fire!  I've had chips smoke in the past, but this was a legit orange flame with hissing and crackling.  My dog, who usually sleeps under my workbench, immediately ran out of the room.  I cut the power and things were fine, though there was some obvious damage to the board.

What happened?  It turns out that there are two different 6-pin connectors on this (all?) power supplies, one for the motherboard and the rest for PCI-express boards.  Well, I had just grabbed the first one I saw and plugged it into the board: it turns out that the CPU and PCI-express plugs are keyed compatibly, but have opposite polarity!  So instead of feeding my 12V->3.3V regulator 12V, I was feeding it -12V, and that was the end of that.  This might have been avoided if I had put a reverse-polarity-protection diode; the power supply is perfectly willing to put out enough current to fry any reasonably-sized diode, so I would have needed some sort of over-current protection as well.

I was actually able to get some use out of this particular board; I had to remove the charred regulator, but then I just fed the board 3.3V directly and then the 1.8V regulator (upper right) worked just fine.  But there are a couple more problems with the board that you might be able to notice.

The first is the unpopulated barrel-jack socket in the bottom left.  You can see that the silkscreen calls for a center-positive plug, but the 12V line goes to what is definitely *not* the center of the plug. This was a result of me misinterpreting the schematic symbol for the Eagle part I obtained (from SparkFun, like usual), and not double-checking the board layout to make sure it matched my expectation.  I wasn't too bummed about it since this was just the backup way of getting power onto the board, with the ATX connector being the intended one.  That being said, I think I would have rather had the barrel plug because that cable is much more flexible than the ATX power supply cable, which ends up more-or-less fixing the orientation of the board while I use it.

The second major problem with this board is the messed up oscillator, the silver box roughly in the middle of the board.  For this one, this was a mistake in me reading the datasheet: for some reason I thought the Enable pin was active-low, when in fact it was active-high, so I in order to get it to work I had to cut some traces and green-wire.

I wasn't able to get the 12V circuitry working on the board that had the fire -- even after replacing the IC that caught on fire, the board didn't work correctly.  At that point I decided that debugging a previously-on-fire board was probably a losing battle, so I ordered the parts to make another one, which now works quite well (barring the missing barrel plug socket):

Burnt board on bottom, new board attached to the rest of the system and plugged in.

Burnt board on bottom, new board attached to the rest of the system and plugged in.  You can see 30-AWG green wires around the bad oscillator.

Not recoverable but still interesting: jtag board

I'm using JTAG a fair bit in my current project, for which I built my own JTAG adapter.  It was an interesting exercise to understand how the whole thing works, but the result is pretty messy:

JTAG setup

JTAG setup

It's a little tough to see from this picture, but the way this works is I have a USB connection from my laptop (grey cable coming in from the left), which connects to a CP2103 (USB<->UART chip) breakout board, which connects to an arduino-like board, which then connects to a breadboard where I'm doing level-shifting, which then connects down to the project itself (out of view).  I've found the laptop->CP2103->atmega->breadboard toolchain to be quite good for prototyping and development, but it's getting cumbersome and involves quite a few wires.  So, I decided to coalesce all of this into a single circuit board in order to make it easier to manage, and here's what I came up with:

New JTAG adapter.

New JTAG adapter.

As you can see, the through-hole components are unpopulated because I realized that the board wasn't going to work.  This board has given me quite some trouble; here's the first run of it, can you spot the difference?

Old, even less-working jtag adapter design

Old, even less-working JTAG adapter design

The problem was that I used the wrong footprint for the FT230X, the IC right next to the USB port.  (Note: SOP != SSOP, not by a long shot.)  I noticed the problem pretty quickly, but only after I had sent out the design to OSH Park for boards and OSH Stencils for a stencil.  It was a pretty easy fix, so within a day I sent the new boards to OSH Park, but I forgot to have another stencil made!  So yeah, there were a few issues through that process.

I actually managed to use the wrong stencil for the board with reasonable results.  The only main problem was that the USB connector was completely misaligned and not connected; not sure if this was a result of the wrong stencil or a bad footprint or what (I used a generic micro-USB footprint, not the one suggested for this particular part).  Re-soldering the USB socket was particularly hard because the FT230X, the TSSOP next to the connector, is so close that it was very difficult to fit the soldering iron or multimeter probe in there.  (This kind of proximity issue is actually one of my most common ones, and I'm still not great at anticipating it.)

So I got the USB port resoldered, but then I noticed two problems with the ATmega part of the schematic: first, I had forgotten an ISP header to flash the code.  For my existing jtag setup I had pre-programmed the chip with a bootloader, and since it was talking serial I could use the bootloader to load new versions.  My normal approach is to use my ZIF-socket-programmer to burn the bootloader for DIP chips, but this is a QFP so I was out of luck.  What I did instead was I soldered it to another project that uses the same footprint and does have an ISP header, then burnt the bootloader onto it, then removed it and resoldered it to the current board.  This was actually all-for-naught, since I burned the wrong bootloader code onto it, so I actually soldered tiny leads onto the four relevant IC pins, and then connected that to the programmer, and flashed the correct bootloader.

Actually, I wasn't able to do that right away, since I noticed that I had messed up the ATmega crystal circuit.  It's a very simple circuit and I guess I assumed that I knew it well enough to not look it up again, and so of course it ended up messed up.  I had to do some more greenwiring, which included soldering some through-hole capacitors onto the back of the board.  But after I did this, I plugged in the USB and saw the bootloader flash the LED!

In the midst of all of this, the USB connector came off.  This micro-USB socket has only SMD pads, and is very space efficient, but is very hard to hand-solder (I was doing this with the wrong stencil so I didn't reflow this part).  It actually left me in a pretty weird predicament since all the connections broke except for one, while the cable was still plugged in!  Do I rip the last pad off, potentially lifting the pad?  Do I use pliers to try to remove the socket from the cable without putting force on the board? (tried that and it didn't work)  Or do I use my soldering iron to undo that last joint?  I was pretty wary of doing that last one, since I learned the hard way that for my fancy Metcal soldering iron the soldering head is actually electrically hot, and Bad Things can happen if I use it on a live circuit.  After I tried using pliers unsuccessfully (not possible to get a good hold while the board was still half-attached), I finally just resorted to using it and everything was fine.

After reattaching the USB socket, I was able to boot up my circuit and use the bootloader to flash my JTAG programmer!  Everything was going great until I then connected the adapter to my JTAG circuit, at which point it promptly stopped working -- I don't even get the led flashes from the bootloader any more.  I'll look into it more later, but for now I'm going to put my effort into designing v0.2 of this circuit.  So at the end of the day, this circuit still isn't working, and I'm not sure it's worth investing the time to figure out why, because it lacks the breakouts to make the debugging easy.

On top of all of this, I broke one of my brand-new oscilloscope probes.  I'm not 100% sure how it happened, but my guess is that it's from when I was using the heat gun to desolder the QFP ATmega multiple times, since I left the probe in that area.  I learned my lesson and moved the scope to a safer part of my bench, away from the heating elements (plus also closer at hand, now that I'm learning how much I use the knobs).  Luckily, 100MHz probes are only about $7 each, and the ones I bought even come with little tips to make it easier to grab IC pins.


This post ended up being less informative in the way I thought, but actually ended up being a pretty representative example of what it's like when I debug circuits.  I'm sure that for anyone experienced with electronics, what I've said is extremely obvious, but I know that when I was starting out I had absolutely no idea what kinds of things I was going to encounter.

Filed under: electronics No Comments

Buying an oscilloscope

I guess this post is going to be the second in an unintentional two-part series on "things that I've spent an inordinate amount of time thinking about yet aren't the core of the electronics issues."  The first was about how I've improved my organizational setup, and this one is about the process of buying an entry-level oscilloscope.  I guess my hope is that it might be helpful for someone going through the same process; it's nothing fundamentally difficult about it (the different specs are well-defined and -described elsewhere), but it's certainly going to be the most exotic thing on my bench, and I found surprisingly little out there about how to actually make a choice.

My current setup

What I have currently is this oscilloscope that I bought from SparkFun (though it looks like it's sold by many other places as well), and for $60 it's actually quite handy and gets used a lot.  That said, I've started to run into some limitations with it; the most obvious is that it is limited to about 1 megasamples/sec.  That's my estimation based off an assumption of one data point per pixel it displays and the fact that the highest working resolution is 5us/div (they do let you go finer, but then the display stops working).

Does hitting that limitation a few times mean I should invest hundreds of dollars in a new scope?  Well, there are definitely ways I can imagine a "real" oscilloscope being better and more useful (larger screen, knobs instead of all buttons), but that doesn't really mean much concretely to me, so I did some searching on the internet to try to figure it out.

Which was probably a bad idea, because the internet always seems to be full of people seeking validation for their purchases; I don't think I've ever seen a comment or blog post from someone who didn't buy something and then said that they agreed with their decision, or someone who said that they opted for the more expensive choice and then regretted it.  Maybe this is an accurate portrayal and people are almost always happy buying things they want, but I think it has more to do with sample bias and the desire to justify any money spent.  But it didn't really matter, because at this point I was hooked so I decided to look around.

Oscilloscope options

After doing some searching, there seem to be a few options out there for someone looking to buy their first scope.  In increasing order of cost:

  • Don't buy one and use a multimeter
  • Get a USB/"toy" oscilloscope
  • Buy a used analog scope
  • Buy a chinese digital scope
  • Get something expensive

I did the first one (not buying anything) for a while, then did the second one when I got myself that $60 scope.  I think maybe until a few years ago the "buy used" option might have been very good, but it looks like the prices for scopes have come down enough that that wasn't an attractive option for me.

For chinese scopes, it looks like the most popular manufacturer is Rigol.  Their DS1052E (50MHz) model in particular seems extremely popular as an entry-level scope; hackers figured out that it was the same hardware as the higher-end DS1102E (100MHz) scope except for some firmware crippling, which they were able to remove.  For a while Rigol tried updating the firmware to make it "unhackable" but of course that's not a winnable battle, and it looks like they've given up and decreased the price of the DS1102E to what the DS1052E used to be ($399) so it's now quite a good deal.

The DS1102E seems to be the cheapest reasonable scope out there, is the #1 seller on Amazon, and is the one that kept on coming up in every discussion I found, so it seems like a pretty good option.

Making the decision

I looked around for any suggestions that other people have, and true to form the internet is full of advice to go big or go home.  In particular, I was curious about getting a "MSO", which is basically a scope with an integrated logic analyzer.  Rigol offers a MSO version of the DS1102E, the DS1102D, for about twice the price.  If you start considering that, though, there are a lot of other options in that price range, and a lot of people trying to convince you you have to spend even more money.  A common argument goes along the lines of "if you're going to buy the more expensive item eventually, you might as well buy it now" -- you can see that kind of thing on this blog, which is pretty much the only other example I could find of someone walking through their decision to buy a scope.

In the past I've been pretty swayed by this kind of argument -- the logic seems unassailable: if you're going to buy it anyway, don't waste your time or money on something in between.  But now I'm learning that this really isn't true: if you're having trouble with a decision like this, it's most likely because you don't know exactly what you want!  So the initial purchase is an investment in knowing how to spend your later money better.  So I decided to back from the $1k+ scopes and take stock again of why I wanted one -- I had started researching these on a whim and now I was being upsold quite high!  In the end, I realized that the main reasons to buy a scope are 1) the upside seems decently high, since based on what other people are saying they use theirs for, it has a good chance of accelerating a interest that is currently time-constrained, and 2) I feel reasonably confident that I'll get some use out of it, since I've maintained my interest in electronics for a while.

I could go on and on about how I tried to evaluate those two points and how I've misjudged them in the past (just look at my camera equipment that got used only once), but I'm going to wrap it up here and say that I bought myself the DS1102E for $399 from Amazon (prime!), and feel good about it for now though I haven't received it yet.


And here it is!  This is a picture of it measuring about 200mV+-200mV of ground bias across my circuit -- not very good!  So far it's been very fun to play with, but we'll have to see about its long-term usefulness.

2014-01-04 13.56.07

Filed under: electronics No Comments

New parts organization scheme

I don't have a particularly large or complex electronics setup, but that hasn't stopped me from searching for the "perfect" way to organize everything.  I think I tend to obsess over my plan because 1) it's easy to feel like it's critically important, and 2) it's something that can be difficult to change.  In software work I've really subscribed to the iterative approach to engineering, but for multiple reasons I have trouble applying it to electronics even though I feel like it should transfer.  I think the first reason is that iteration often involves spending money, which feels more irreversible than spending time -- I'll talk about this more in my next post.  The other reason is that iteration is more difficult when the work is physical, since you can't automate tasks anywhere near as easily.

Anyway, I recently changed how I think about organizing my parts, and since I agonized over it for a while I thought I'd post about it.

My previous organization scheme: part-based

When I started out buying electronics, I left everything in the bags they got shipped in, but this quickly became unreasonable.  I started looking around for what other people do, and it seems like the most commonly-talked about strategy -- and also the one I had seen in the labs at college -- is to have drawer units where each drawer holds a different part.  So, I dutifully set out and bought a couple of those units, and started stocking them with the beginnings of an electronics inventory:

2013-08-30 03.50.28

The kind of organization I thought one needed

One thing I quickly found was that I was buying a TON of different components.  If I wanted to experiment with a different diode, does that mean it should get its own drawer even if I only have 10 of them?  What about that single 555 timer that I bought in case I wanted to play with it?  And even for bread-and-butter parts like resistors, should I have a different drawer for every single resistor value?

Eventually I came to the conclusion that the "one-part-per-drawer" system requires a decent quantity of each distinct part in order to make sense.  So, the next thing I did was I bought a pack of coin envelopes, to serve as a means of subdividing parts within the drawers.  Unfortunately the envelopes don't quite fit inside the drawers; for some I cram them in anyway, but for others I 3d-printed some boxes of the right size, and put ~20 envelopes in each:

2013-08-24 03.38.55

The way I still organize resistors/capacitors/leds, though now I use all SMD parts. TE stands for taydaelectronics which is a great place to buy cheap components.

This works great for the parts that I use in every project and need quick access to; I still use this scheme for resistors, capacitors, and leds.  This also has the benefit that I can write more information on the envelope than was feasible to put on the drawer, so I can put the exact part number for later reference.

I thought this was about as well as I could do, until I found myself doing something quite different: I started buying parts for a project at a time, and until I was ready to start the project I would leave the parts in the shipping box.  This was mostly out of laziness, but it made it much easier to gather the relevant parts when I finally was ready.  I also noticed that I was still buying tons of new components; I tried to use ones I had bought before when I could, but each project usually used at least 5-10 new parts.  These observations led to my new-and-much-improved system:

New scheme: project-based

The combination of 1) using new parts way more often than I anticipated, 2) noticing how much easier it is to start a project when all the relevant pieces are already together, and 3) running into the issue of not remembering why I had bought a certain part (which project was that particular regulator for? which projects did I decided an ATmega8 was ok and which ones are the ATmega328's for?), all led to me to adopt this system that I had already begun using.

So, what I'm doing now is I put all the materials for a project into a quart-sized ziploc bag, and then I put all those bags into a box under my desk.  Actually, I'm working on a new project that has multiple sub-projects, so for those I put all the quart bags into a gallon bag which then went into the box.  The choice of ziplocs and a cardboard box aren't final -- I'm using them because I didn't have to spend any money in order to test if I like the overall idea, but they're actually working quite well.  Eventually I might buy some larger stacking bins that might be easier and more compact.

So far this has served me pretty well, especially since I realized that a project has more components than just the electronic ones I had set out to organize: for instance, the PCBs, stencils, and any assembled versions need to be kept track of as well.  In the past I had separate places where I stacked all PCBs, or all stencils, or all built boards, which was fine when I had a total of five projects or so, but the new system makes it far easier to find the parts, and also find a home for things that used to not cleanly fall into one of the piles I had (ex: where should I put notes about a project?).

Long story short, I feel way better about my organization once I made the switch from placing similar parts together, to organizing everything by project.  I'm not sure why I was so convinced that things had to be organized by part; this change might seem like a small deal, but trust me it makes a huge difference.

2014-01-04 00.53.00

It may not look it, but I find this system way more effective and usable than the drawers.

Filed under: electronics No Comments

Quadcopter update: bldc boards ready

A couple weeks ago I wrote about how I was building a brushless motor (BLDC) driver board, for the ultimate goal of using them in a quadcopter design.  Well, the boards came in about a week ago and I'm finally ready to show off what they look like -- and maybe complain about how much work they were in the process :P

The boards

You can check out my previous post for more about the exact design (or find the source code on my github), but as a very brief summary, there are three main stages to my board: the digital/control stage, the power stage, and the back-emf sensing stage.  The digital stage is mostly centered around an ATmega328 which controls the pwm, commutation, and does the back-emf sensing; the power stage involves six high-efficiency mosfets and associated components, and the back-emf sensing stage is an LM339 comparator and an analog mux that feeds it.  Here's the board design I came up with:


And here's what these things looked like when I got them back from OSH Park:

2013-09-18 17.56.56

These are by far the most involved boards I've made so far, and I still definitely get a rush seeing my design turned into a fine-precision physical object.  I bought six boards, even though I only need 4, originally because OSH Park sells boards in quantities of three, but it turned out to be quite nice to have extras.  I bought enough parts to assemble just one of the boards, since my I didn't have too much confidence in the boards or part selection, and then set off to get the first board working.

Assembly woes

I started hand-soldering the first board, and things were going ok for a while: I feel like I'm starting to get the hang of TSSOP/QFP/0402 parts.  There are definitely things about the layout that made it tough to assemble, that I want to avoid in the future: I put some components too close together, making it tricky to keep their solder separate, and some components were very difficult to place and access once the surrounding components were in place (in particular, the 0402 decoupling caps between some of the ICs).  But these issues were dwarfed by the trouble I had with another problem: bad footprints.

I've been getting most of my package footprints from the SparkFun eagle libraries, or directly copying the manufacturers recommended land pattern when I need to create a new part.  I guess I got a little overconfident with this board, because I used a couple new SparkFun footprints without verifying them first, which ended up causing a depressing amount of desoldering+resoldering+touchup work on those parts.  First off, I'm not really sure how this happened, but their 0805 footprint is way smaller than I expected compared to an 0805 part; the pads are only as wide as the component itself, which means that you need to leave extra space around the pads for the component itself (as opposed to their other footprints such as 0402/0603/1206).  Luckily I only had one place where this was really an issue, with three 0805 parts next to each other; for the subsequent boards I side-stepped this issue by putting 0603 caps on those footprints, which turned out to be fine.

The big problem, though, was with the resistor array footprint I used.  This was my first board where I used these parts; they seemed pretty promising, giving a pretty good area reduction and reducing the number of components (if not the number of pads).  I grabbed the RES-ARRAY footprint from the SparkFun libraries, and put 8 of them on my board.  Big mistake.

The SparkFun footprint was totally different than the parts I had ordered.  I'm not really sure how this happened, but the pads ended up being too close together, and also too short, which meant that the component completely covered the pads when placed.  This meant that it was extremely hard to get solder to the pad, especially when hand-soldering, but I also had difficulty reflowing these parts (though that did turn out better).  I went through many many many many cycles of desoldering the array, desoldering the pads, resoldering the chip, removing extra solder, checking for opens or shorts, and repeating.  I definitely spent the vast majority of my touchup/debugging time on these parts... and unfortunately I have more boards coming in with the same footprint.  Luckily, even though the footprint wasn't that close, I was able to eventually solder all the resistor arrays, and I didn't have to scrap the boards.

The last part of the assembly was the power stage, which posed it's own challenge: I designed the power stage to handle high current (I was shooting for 20A though I doubt it can actually support that), which means that there are large copper pours with lots of thermal conductivity to the power stage components.  At one point, I actually got the soldering iron stuck to a blob of solder -- it was wicking away so much heat that the solder was able to solidify onto the iron!  It was also interesting to solder the exposed pads of the mosfets: I put a number of vias on the pad for this purpose, which actually worked quite well (maybe too well, since I ended up using too much solder).

After many hours of work, I finally got the board assembled:

2013-09-20 02.22.08

I'm blocking the blue LED because it is too bright for the picture.

Getting it to work

I'm going to skip past the part where I spent hours tracking down an issue I thought was with the design but turned out to be just another short in one of the resistor arrays.  After fixing all of those, I got the digital stage working, and the power stage working as well.  I complained in the past about how difficult it is to debug a sensorless bldc design, because the back-emf sensing only works at high speeds.  On the other hand, it definitely was nice that the three stages (digital, power, back-emf sensing) could be addressed sequentially: I first left the high-voltage disconnected, and tried to see if I could get the ATmega to work; then I connected the 12V rail and tried to see if I could slowly step the motor without any issues.

I had a lot of problems when it came to the back-emf sensing stage, though.  I overbuilt this part of the system to give myself flexibility if I wanted something different: I feed the three sense inputs through an analog mux, since you only need to ever look at one of them at a time, and then fed the selected voltage into a comparator, where I compared it against three reference voltages, and then fed the outputs into the ATmega.  I breadboarded something similar, but I hadn't used an analog mux or this particular comparator, so suffice it to say, my design didn't work out of the box.

The first issue is that I bought the wrong part.  I don't know how this happened... but I designed for a 4052 dual 4-to-1 mux/demux, but instead I bought the 4051 8-to-1 mux/demux.  No problem, I'll just put the 4051 on a breakout board and manually wire it up:

2013-09-26 00.58.29

You can see the 4051 mux on the left board

No luck -- it's still not working.  Using my DIY scope, the issue seems to be that the analog mux was clipping the output voltage at 5V -- which is weird, since the datasheet says you can control large voltages with logic-level inputs.  Reading it again, though, it specifically meant large peak-to-peak voltages, which is assuming that your negative peak goes far below ground, to the analog negative rail.  I have no idea why this part includes two negative supplies instead of two positive supplies, but the result is that I actually needed to power this chip from the 12V rail, but when doing this, it no longer takes logic-level inputs (Vih=10V)!  So even if I rewired the board to supply 12V instead of 5V, I'd still need to shift up the control inputs, which involves a few more components than I think can really be bolted on.  Things were looking kind of bleak.

Then, I decided to try something: I hard-wired just one of the sense inputs to the mux, and changed the software to only do back-emf sensing one third of the time, when that specific phase was idle.  It turns out that this ended up being fine!  I suppose that I could have better or faster control of the speed by sensing it three times as often, but qualitatively the motor seems to drive just fine.

I wish I had taken a picture or video of it at this point, but to my huge relief the board was successfully driving my test motor.  So, it was time to order more components for the other boards.

I decided to slightly change the components to reduce cost; I decided to make four additional boards (I didn't trust my prototype board after cutting it up so much), and that plus the RC supplies were starting to add up in cost.  I made two substitutions: I used cheaper 4mΩ MOSFETs (the original ones I picked were 2mΩ), and I switched from ATmega328's to ATmega88's, since the code size was relatively small.  Also, I ordered a stencil for the board, partially because I wanted to try stenciling and I found OSH Stencils (no relation to OSH Park) that produces them pretty cheaply.

Fast forward to getting the new parts...

Assembling the other boards

My plan was to first assemble board #2 (the original hand-soldered board was board #1), to make sure the new stencil+reflow process worked, and then assemble boards #3 #4 and #5 at the same time.  Here's my first-ever attempt at using a solder paste stencil:

2013-10-01 00.15.07

I tried to not put much on there since I put those vias on the MOSFET pads specifically for hand-soldering, but I was worried that in reflow the solder would get sucked through (which it did).  Even ignoring that, the paste application was pretty bad; I must have jostled the stencil or board while I was applying it.  (Pro tip: apply the paste away from the fingers you're using to hold the stencil, to best keep the stencil flat and in place.)  Here's a closeup:

2013-10-01 00.15.44

Surprisingly, this is pretty much good enough

My past experiments with reflow soldering showed me that it's far more important to have the right amount of solder, and the process is hugely forgiving to the exact placement of the solder.  So, despite the fact that most of the footprints have barely-discernible smears of paste, I decided to go ahead with this board.  Either way, it will give me good insight into how precise the solder application needs to be.

Well, the answer is a little more precise than what I did, but not too much more:

2013-10-01 01.04.13

Picture of several solder jumpers, along with a capacitor that has been pulled off its second pad.

Above is the result: everything is in the right place, but you can see several solder jumpers in the above picture, along with a decoupling cap that has been completely claimed by one of its pads and is sitting vertically.  All in all, I was actually pretty impressed by how the results came out -- this is far fewer jumpers than I would have created soldering this by hand.  I just went through with some desoldering braid and cleaned it up, and used the multimeter to show that electrically things looked good.  Except, of course, for the resistor arrays... I had to pull a bunch of those up and resolder them by hand.  In fact for this particular board I was unable to get one of the arrays soldered before ripping up its pads; luckily it seems like those resistors were superfluous anyway, so I just replaced them with 30AWG wire.

Migrating from an ATmega328 to an ATmega88

So, according to what I read on the interwebs, the ATmega88 and ATmega328 are supposed to be interchangeable.  What I found was that while, yes, they are pin-compatible and use the same instruction set, you can't just drop one in for the other and expect it to work.  There are a few reasons why, apart from the obvious one that they have different amounts of program flash and RAM:

  • The interrupt tables are different.  In the 88, each interrupt vector is 1 word (2 bytes), but in the 168/328, they're 2 words (4 bytes).  This isn't too big a deal, since the compiler will generate the right table for you (or maybe it's one of my libraries, not sure), though you do have to tell the compiler that you're targeting a different part.
  • The fuses are very slightly different; this was probably more confusing than actually damaging.
  • Finally, the generated code is different, with slightly different timing characteristics!  I'm not 100% sure what the exact cause is, but my guess is that it's because the compiler emits "rjmp" and "rcall" instructions on the 88 instead of "jmp" and "call" on the 328.  Tiny differences like this probably don't matter for most projects, but I'm trying to commutate the motor with sub-microsecond accuracy, and the reduction in function call time drastically changed the timing parameters required.

In the end I got the ATmega88's working just as well as the 328's, and learned more about them in the process, but I'm not sure if I'll do this again.  This is especially true due to the fact that the price savings from going from an ATmega328 ($2.77) to an 88 ($2.13) is less than from buying the 328's in bulk ($1.74 @25), so for ATmega's it seems more worth standardizing a part and buying more of them, than trying to pick the perfect part for each project.  I didn't want to do that for this project, since I'm not sure if I'm going to stick with TQFP parts or if I can make the jump to QFN parts -- but that's a different story.

There was one last problem with the board: I had removed the 4052 part from the design, but that unfortunately didn't mean I could ignore it, since its footprint and traces were still there.  If you look at the top part of the above photo, you'll see that there are a couple jumpers on the unpopulated footprint; the one on the right is a jumper between the 5V rail and a motor lead, which needless to say, caused havoc until I cleaned it up.

Building the rest

Now, it's time to build the other three boards.  At this point, after several nights of working on it, I'm getting pretty tired of soldering, especially for these boards.  My hope was that by assembling all three at the same time, I could significantly cut down on the assembly time.  For instance, I find that when assembling a board I seem to spend more time "picking" than "placing" components, at least with this design where there are many different components (many different-value resistors, for instance), and my hope was that by doing three boards I could amortize the picking across three times as many placings.

2013-10-03 01.17.07

Three boards in my reflow toaster at once

It turns out that I was mostly right: while board #2 (the first reflow board) took me about an hour to solder, boards #3 through #5 took a combined 90 minutes to solder.  It's not really a fair comparison since there was some aspect of me overall being faster at these boards (the time-per-board would have gone down even without doing multiple boards at once), but it was definitely a welcome speedup.  The big difference, though, was in the touchup and debugging stages.  First off, my solder paste application was better, requiring fewer manual adjustments -- but still some, so I still need to work on my process:

2013-10-03 00.19.36

Getting more used to solder stenciling

The big wins, though, came from reductions in the debugging time.  At this point I only ran into issues that I had already had with the first two boards, and I had already mapped out the hot-fixes I needed to make, so I was able to make all three boards in a night, as opposed to the first two boards which each took an entire night themselves.

Final product

I haven't taken any videos yet, since right now I can still only run one motor at a time (due to power supply limitations), but here are my assembled boards:

2013-10-03 04.38.03

I assembled them left-to-right, top-to-bottom (board #4 is in the bottom left), and you can see the marked reduction in extra wiring.

There are a lot of things I would change if I wanted to put together a v0.2.  For instance, I didn't put a pull-down resistor on the PWM line, which means that when I hit reset the driver input will be left floating, ie the mosfets will still be on!  I found this important enough to change that I actually soldered 10k resistors onto these boards.  There are also a number of places where I deliberately overbuilt the circuit to leave headroom (there are still features I want to add) and in general I think the 20A target was way too high -- running a single motor at 1A is enough power to blow things off my desk, and forceful enough that I feel the need to wear safety glasses while testing.  If I were to start from scratch, there are also some all-in-one BLDC driver chips that could have replaced... pretty much all of my circuit.

But the boards are working, so that's it for this step!  I'm not sure how much current these things can handle, but at 1A the boards didn't even feel warm at all, and based on feel, I think 1A is more than enough current to hover the copter, so I may never fully stress these things.  From here, I need to attach the final wiring solution (18AWG wire instead of 22, and with proper connectors on the end), and follow through with my plans to create an ATX-to-XT60 connector that would allow me to power all four boards from an old computer power supply, at which point I should be able to drive all four motors at the same time, and hopefully achieve (uncontrolled) flight!  The final piece of the copter is the central control board, which I just got a notification that OSH Park has shipped and should be here in time for the weekend :)

Filed under: quadcopter No Comments

Choosing FPGA parts

I spent some time this weekend looking into different FPGA options for potential future projects; I've been using the Spartan-6 on my Nexys3 board, and I created a simple breakout board for it, but I started to learn more about the limitations of staying within that single product class.  The Spartan-6 is limited on the high-end, though Xilinx will happily advertise several alternative lines such as their 7-Series, of any of their Virtex chips, which can cost up to $20k for a single chip.  One thing I was interested in, though, is what options there are on the lower end of the Spartan-6.

Cheaper options

There are two sides to this: the first is that the cheapest Spartan-6 is about $11 on Digikey, and the second is that the smallest package (both in terms of pin-count and physical size) is a 144-TQFP which has nominal dimensions of 20mm x 20mm (not including lead length).  You can see from my breakout board that it took me about 2 in^2 of space to fit the 144-TQFP with its connections, and I didn't even break out all the pins in order to save space.  This puts the minimum cost for a one-off Spartan-6 board at around $20, which would be nice to bring down.

So, at this point I started to look into other lines.  Doing some searching on Digikey, there are only a few parts that come under the $10 mark: older Spartan parts such as the Spartan-3A, and Lattice FPGAs such as the ICE40.  The Spartan-3A seems pretty promising, since it's quite similar to the Spartan-6 both in terms of toolchain and electrical properties.  The smallest Spartan-3A costs $6 and comes in a 100-QFP package, which is about half the size and cost of the smallest Spartan-6.  I haven't gone through and created a breakout for this part, but assuming the size scales somewhat linearly, it should come in at about 1 in^2 for a total cost of about $11.

Once I started to think about this, though, I noticed that the cost driver seems to be the fact that Xilinx puts so many IOs on these parts.  Maybe for "real" purposes the minimum of 102 IOs on the Spartan-6 (68 on the Spartan-3A) doesn't seem like that much, but for simple boards that I want to make (ex: VGA driver on an SPI interface) this is way more than I need.  So, let's look beyond Xilinx FPGA parts and see what else is out there.

As I mentioned, the other sub-$10 FPGA parts on Digikey are Lattice parts.  I don't know much about that company, but some of their parts are quite interesting: they offer an ICE40 $1.65 FPGA (which apparently costs $0.50 in volume) that comes in a 32-QFN 5mm x 5mm package, or a slightly larger $4.25 part in a 84-QFN 7mm x 7mm package.  They also offer a large number of cheap BGA parts, but the pitches on them are 0.4mm or 0.5mm, and I calculated that the OSH Park design rules require about a 1.0mm pitch (also that if I use a two-layer board, 256 balls is about the max).  Anyway, the $1.65 part seems interesting; it seems like an interesting competitor to the CoolRunner-II CPLD, the smallest of which is a $1.15 part that also comes in a 32-QFN package.  The ICE40 lacks a lot of the features of the Spartan line, but that's probably a good thing for me since I am not planning on using gigabit transceivers in the near future.  I downloaded the Lattice software to test it out; people complain a lot about the Xilinx software, but at first glance the Lattice software doesn't seem any better.  I'm still trying to figure out how to program a Lattice FPGA without buying their expensive programmer; I'm sure their programmer is a standard JTAG driver, but I'm still trying to figure out how to have their software output SVF files so I can use other hardware.  Overall, I haven't been that impressed by the Lattice software (the installer never finished) or documentation (there are lots of links to Lattice employee's home directories, infinite redirect loops in local help, etc), so I'm not sure it's worth learning this whole new toolchain in order to have access to these parts that I may not need.

But now that I had compared the Lattice parts to the Xilinx CPLDs, I was interested in how much you can use those parts.  To test it, I took the ICE40 sample program of a few blinking LEDs and ran it through the Xilinx tools for the CoolRunner, just to get a quick comparison of the relative capacities.  The sample program takes somewhere between 10% and 20% of the ICE40 part (not exactly sure how to interpret the P&R results), but it takes about 90% of the CoolRunner -- apparently the large counter, which divides the external clock into something more human-visible, is a bad match for the CoolRunner.  There are larger CoolRunner options, but it seems like once you start getting into those, the Spartan-3A line looks attractive since it has way more capacity for the same price.  The CoolRunner does feature non-volatile configuration memory, which does seem nice, but I don't quite understand the cases where the expensive CoolRunner parts make sense.

Larger options

On the other side of the spectrum, I was also interested in larger options.  Specifically, I was interested in options with the best logic-capacity-per-dollar ratio; I'm sure for some use cases you really need a single chip with a certain capacity (I guess that's where the $20k FPGA comes in), but for my purposes let's look at the ratio.  To do this, I downloaded the list of FPGA prices from Digikey, and ran them through a script that divides the "Number of logic elements" field by the cost for one unit.  The "number of logic elements" has different meaning between manufacturers or even product lines (for the Spartan 3A, it's the number of 4LUTs, and for the Spartan 6, it's 1.6x the number of 6LUTs), so it's not really apples-to-apples, but this is only a rough comparison anyway.  Here's what I got, selected results only:

$228.00 with 301000 LE, the Altera 'IC CYCLONE V E FPGA 484FBGA' is 1320.2 LE/$ [overall best]
$186.25 with 215360 LE, the Xilinx 'IC FPGA 200K ARTIX-7 484FBGA' is 1156.3 LE/$ [best xilinx]
$158.75 with 147443 LE, the Xilinx 'IC FPGA SPARTAN 6 147K 484FGGBGA' is 928.8 LE/$ [best Spartan]
$208.75 with 162240 LE, the Xilinx 'IC FPGA 160K KINTEX-7 484FBGA' is 777.2 LE/$ [best kintex]

Those are some pretty cool parts, but looking at the packages, unfortunately I don't think I'll be able to use them. I have a reflow toaster that I've had some mild success with, so I feel like BGA parts aren't off-limits as a whole, but these particular packages are definitely pushing it.  Luckily, these are 1.0mm-pitch parts, which means that according to OSH Park design rules we can fit vias in the ball grid, but unfortunately we won't be able to route between those vias that we make!  So we're going to have to not have vias for every ball; regardless, if I use a two-layer board, I'm not sure how many of the signals I'll actually be able to route out of the grid.  So let's rule anything larger than a 256-ball BGA (the smallest kind for most families) as off-limits.  Here's what we get:

$115.11 with 101440 LE, the Xilinx 'IC FPGA 100K ARTIX-7 256FBGA' is 881.2 LE/$ [best]
$34.25 with 24051 LE, the Xilinx 'IC FPGA SPARTAN 6 24K 256FTGBGA' is 702.2 LE/$ [best spartan]
$39.50 with 24624 LE, the Altera 'IC CYCLONE III FPGA 144EQFP' is 623.4 LE/$ [best non-bga]
$23.96 with 14400 LE, the Altera 'IC CYCLONE IV GX FPGA 148QFN' is 601.0 LE/$ [best qfn]
$15.69 with 9152 LE, the Xilinx 'IC FPGA SPARTAN-6 9K 144TQFP' is 583.3 LE/$ [best xilinx non-bga, and the one I made a breakout for]

Unfortunately it seems like you really do have to go to BGA packages if you want to use anything larger than 25k logic elements, so it looks like my plan might be to first test my ability to use this BGA part by creating a Spartan-3A breakout board, and then using the Artix-7 256FBGA part when I want a large FPGA.

Filed under: fpga 3 Comments

CPLDs: prototype, and breakout

I've recently been intrigued by the idea of using CPLDs in my designs -- there have been lots (maybe 2 or 3!) of times that I've wanted a specific set of glue logic, only to find out it doesn't exist or the output polarity is wrong, and I have to resort to using multiple 74xx chips.  A CPLD seems like a natural solution to this: as mini-FPGAs (perhaps more correctly, FPGAs are mega-CPLDs), you can configure them to perform a large range of combinatorial logic, and you can get exactly the "part" you want.  This means both the exact logic behavior, but also the more-or-less exact pin placement, which I'm increasingly discovering the importance of.  CPLDs are pretty cheap, starting at about $1 on the low end, which is the price of two 74xx chips.  Clearly, they're going to be more complicated than just snapping some off-the-shelf parts in, but it seems like they should be a relative shoe-in.

This is the story of me getting started with the Xilinx CoolRunner-II cplds.


The first issue is that CPLDs, at least CoolRunner-IIs, only come in SMD packages.  Thankfully the situation isn't as bad as FPGAs, where almost all parts come in BGA packages, but it means that I needed to find a TQFP adapter for prototyping (part of the reason why I wanted to make my own).  Here's a picture of the 0.8mm-pitch chip soldered onto the adapter; I was worried about the extra-long adapter pads making this hard to solder, but it turned out to be fine:

2013-09-19 02.17.37

Here's the rest of the circuit this is a part of:

2013-09-19 02.17.45

There's not much on the breadboard in the middle, just a 1.8V voltage regulator, and some level-shifting circuitry (more on that in a sec).  On the left is one of my "activity monitors" that was actually useful for debugging (good thing I've made 20+ of them for testing purposes!).  On the top is a little ATmega328 board serving as a JTAG programmer.

Voltage levels

The first hiccup I encountered was with voltage levels.  The CoolRunner-II has four supply voltages: a 1.8V "core" voltage, and three adjustable voltages (two for the two IO banks, and one "auxiliary" for the JTAG interface).  I was prepared for the idea of the cpld requiring a lower voltage, even though it would mean adding a 1.8V and 3.3V supply.

Once I started to look into it further, however, I uncovered more issues.  First of all the CoolRunner-II is *not* 5V tolerant, even with current-limiting resistors (ie there's a voltage limit separate from a current limit).  Unlike most parts I've dealt with (such as the ATmega328), the CoolRunner-II doesn't have ESD protection diodes, which automatically clamp the input voltages into typically-acceptable ranges.  Although you have to worry about the current you send across those diodes, this means you can interface a higher-voltage signal to a lower-voltage part simply by putting a current-limiting resistor in series.  Unfortunately, this doesn't work for the CoolRunner-II, which means that you have to use some other method, typically involving at least two discrete parts, or a fraction of a different IC that can do this level-shifting.  For most uses this isn't that bad, but for the purpose of reducing the "glue" complexity in the system, it's a step in the wrong direction.

Let's ignore this for now; my thoughts are that I'll probably move designs involving cplds to using a main supply voltage of 3.3V.  As a sidenote, technically running an ATmega at 16MHz and 3.3V is out of spec (ie overclocking), though reading on the internet this seems to be a common thing that people don't report issues with (the issues probably happen at one of the temperature extremes).  For the testing, I wired up some resistor divider down-shifters and a simple NPN up-shifter, since I was running all four voltages at 1.8V.


Now that I had the chip powered up, the next step was to get it to do something.  The CoolRunner-II, and most of Xilinx's (and I presume other peoples') parts are programmed over a 4-wire interface called JTAG.  I won't really get into the details of JTAG, but  for a single chip it looks pretty much like SPI, but the benefit is that it's designed for hooking multiple chips into a chain, so that you only need 4 wires regardless of the number of chips you have (in theory).

When I encounter a new protocol, I usually put a simple shim program on my ATmega328, which listens on the serial interface and allows a computer script to control all the IO pins.  This means I can use Python on my computer, avoiding recompiling+reprogramming, plus giving me more control and visibility into the program.  The downside, of course, is the overhead, but for trying out new protocols that's not as important.  You can find the code here, but in essence it allows you to write the "Blink" Arduino sketch like this:

controller = DebugController("/dev/ttyUSB0", br=500000)
controller.pinMode(13, "output")
while True:
    controller.digitalWrite(13, 1)
    controller.digitalWrite(13, 0)

Using this, I wrote a very simple Python script that let bit-bang'ed the JTAG protocol and was able to get the chip to respond!  It took me a few tries to get the bit timings exactly right (ie when exactly a bit is read by the cpld, and which clock cycles the cpld's outputs correspond to), but I was able to eventually read the part IDCODE out.

The next step was to actually get this thing programmed.  I won't go into how to write the program for it, but suffice it to say that Xilinx's tools are able to produce a "SVF" file, which is essentially a list of JTAG operations that will result in the chip being programmed.  Luckily, SVF is a very simple format and the main hard part in writing a SVF reader+player is to understand JTAG.

I only implemented the subset of SVF that the Xilinx tools output, so it was surprisingly manageable to write the player, which you can find here.  I excitedly started running it on the full programming file, and... it took 5 minutes to program the CPLD.  The obvious thing to do would be to port the SVF player to the ATmega328 and just send the SVF file down instead of the bit-bang instructions, but I didn't feel like doing that; after some performance debugging, I found the issue was that I was waiting for the ATmega328 to respond to each command before issuing the next one, so I changed it to only block when the SVF specified to verify the output, which tends to be at end of long transfers.  I was able to get the programming time down to 25 seconds, which is starting to be bearable, but if I do end up using CPLDs I hope I have time to rewrite the programmer.

Anyway, at this point I had a CPLD programmed as a single XOR gate, and it was something of a rush to see it finally respond when I changed the inputs :)

Improving the build process

One thing I've always been slightly annoyed with when it comes to Xilinx development is how tedious it can be to do a compile-and-reprogram cycle.  For FPGAs, it involves double-clicking a small list item in the ISE interface, waiting, then going to the Impact program, and clicking another rather small button.  This is worse with new custom programming step, since I have to use Impact to generate the SVF file, then go to the shell and program the device.

I thought about adding support for my programmer in Impact, or creating some sort of custom script in ISE (which I'm vaguely aware is possible), but this quickly turned into a dead end.  Instead, it was much simpler to simply take the commands that ISE itself runs (with some help from this site), and put them into a Makefile so that I can live on the command line.  Again, it took a couple tries to get right  -- if you don't erase the CPLD first (the default is to not erase) it won't program correctly -- but eventually I had a working Makefile that could all-in-one program my cpld with only one command and no mouse clicks.  You can find the example project here.

Breakout board

Now that I was confident in being able to use the CPLDs, the next thing I wanted to do was create a simple breakout board with some switches and lights.  Here's what I came up with:

CPLD breakout board schematic

CPLD breakout board schematic

CPLD breakout board layout

CPLD breakout board layout

It's definitely not as full-featured as a real CPLD breakout board, but I just wanted to throw something together quickly for testing.  It takes a 3.3V supply voltage, and has an on-board 1.8V regulator.  It runs the two IO banks at different voltages, one at 1.8V and one at 3.3V.  There are eight slide switches and eight leds, which should hopefully be better for debugging than moving wires around and looking at the multimeter.

Update: I just noticed that I have the two IO banks backwards.  This mainly means that the voltages on the two banks are swapped, which means the LEDs won't work without some hot-fixing.

Other ideas

One thing I want to do with this is create a simple ATmega project board, but with a CPLD as configurable router.  Most of my projects only involve a few IO pins on the ATmega, but those pins tend to differ project-by-project.  I tried to think of ways to reduce the pin count on the board, such as by connecting multiple pins to the same pin header, but using a CPLD seems like a way around this.

Also, since CPLDs are somewhat like miniature FPGAs, I think I'm ready to put together my first FPGA board.  But first, my BLDC driver boards have arrived, so I'll probably play around with one of those.

Filed under: electronics No Comments

PCB miniaturization: the limit

I've done a series of circuit board layouts of my simple "Activity Monitor" circuit, at first to teach myself PCB design and try out getting them made, and lately to test different different pcb limits, primarily miniaturization.  In my last post about it, I talked about putting together a board I thought was high-density, and how I submitted a new design that was even more dense.  Well, I got back the boards today and here's how it went.  First up, here's a picture comparing the four iterations of the boards:

2013-09-18 14.35.44

The left-most board is my first attempt, and the first circuit board I ever created.  It uses through-hole components exclusively, and measured 1.69" x 2.55".  The green boards are my second attempt, my second circuit boards ever, and my first experimentation with surface-mount components.  I could have made this smaller if I wanted but the goal for that iteration was to try out SeeedStudio (hence the non-purple color), and to test smd components.

The next pair are my first attempt at miniaturizing the circuit, using all surface-mount components and taking out "extras" like the mounting holes and second (duplicate) pin header.  I also bumped up the number of signals from 4 to 6, so there's actually about 50% more logic in this board than the first two iterations.  Since this was such a reduction from the previous iteration, I didn't want to shrink it any more than this, despite thinking that I could.  Here's a close up of the most recent iterations:

2013-09-18 14.36.01

As you can see, I made the fourth and final rev smaller mostly by taking out the spaces between the components, but also by breaking symmetry and hand-routing the board, allowing me to pack the components this tightly, getting down to a final size of 0.85" x 0.48".  Here are pics of the soldered board:

2013-09-17 23.33.20


Sorry for the poor image quality -- I had to take these through my cheap 10x loupe to get any reasonable level of detail.

2013-09-17 23.34.06

There are a few things I learned from this: the first is that average density doesn't matter at all; all that matters is local density (ie space on the other side of the board doesn't make the current side any easier to solder).  When I was making these I was worried about "how small the board is compared to the number of components", but this really doesn't matter compared to how close any two individual components are.

The second thing I learned is that the order in which I soldered the components is even more important at this scale.  The method I've settled on for most boards is 1) tin one pad for each component 2) pick out all the components for a type and attach them to their pads 3) go back and fully solder all the components.  This didn't work out so well on this board, since by the time I had placed the 1206 capacitors, the TSSOP parts were very hard to get to.  Instead, I fully-soldered the TSSOPs first, which made it much more feasible, though it through off my method.

This worked fine for assembly, but not for any rework: I wanted to change some resistors out (the new LEDs I tried were too dim), and I resorted to pulling off multiple parts in order to get access to the resistors I wanted to remove (if I had solder tweezers maybe this wouldn't have been an issue).

The last thing is that I was somewhat validated in worrying about putting the pads close together: when I tinned a specific pad, the solder ran into the next one.  It turns out that these were connected by a trace so it was fine, and perhaps the trace is what allowed the solder to run, but overall I am now more worried about that.


So in conclusion,  I feel confident that this density is hand-solderable, especially now that I have 0.012" solder and a 0.4mm soldering iron tip, but I'll probably scale back somewhat, especially around "tall" items like the 1206 capacitors (which I'm not planning on using anymore anyway).

Filed under: electronics 1 Comment

Rescuing a mis-programmed ATmega328

I had messed up one of my circuit boards, and in the debugging process I wanted to eliminate the external crystal as a problem (since there are so few other components in a bare AVR circuit).  I looked at the ATmega328 manual, and found that it features an "Internal 128kHz RC Oscillator", which sounded safe enough.  I pulled out my Arduino-based ISP programmer, and set the appropriate fuse to select that clock.

The first thing that I realized after doing this is that 128kHz is 128 times less than 16MHz, so that triple blink that happens when you start up your Arduino, that usually only takes about a second, will take on the order of minutes in this mode.  I never had the patience to actually sit and wait this long, but the next option in the Clock Sources list is a "Calibrated Internal RC Oscillator".  I had stayed away from this since I didn't want to calibrate it, but it seems like you don't have to calibrate it yourself if you're willing to tolerate a 10% frequency uncertainty.

So the ATmega went back into the programmer, but then I got a message along the lines of "invalid device signature: 0x000000".  Uh oh.  I knew that this was a possibility: for some reason, the ATmega parts use the programmed clock source when in programming mode, instead of defaulting to an internal source, which means that it's possible to program your ATmega into a mode that it is no longer programmable.  I knew of this issue, so made sure to not set it to "external clock" mode, so I was surprised that it was still unprogrammable.

After doing some researching, I learned the problem is there is a maximum programming speed based on the clock speed of the target ATmega, and my Arduino-programmer was exceeding it.

Slowing down the programmer

Ok, time to dive into the ArduinoISP source code.  It's using a lot of registers that I'm not familiar with, but one that looks promising is the "SPCR" register in the spi_init() function.  The ArduinoISP sketch uses the hardware SPI support, and SPCR is the SPI Control Register.  Looking at the docs, the bottom two bits of this register control the SPI clock speed, which seems promising -- but the sketch already has them set to the minimum setting of 1/128 of the cpu clock.  I forget the exact minimum ISP clock, but it's smaller than the target's cpu clock, and since the two ATmega's clocks were off by a factor of 128, this wasn't going to work.

One thing I debated doing was to reduce the clock speed of the programmer ATmega.  If I had alternate-frequency crystals, it would have been decently easy to replace that, though I'm not sure what other effects that would have on the system (would probably screw up the baud rate calculation for the serial port).  But, alas, I didn't, so the option would be to reprogram the programmer to use a different clock source, and I wasn't very confident in my ability to do that.

Instead, I decided to modify the programmer's firmware.  As I mentioned, the ArduinoISO sketch uses the hardware SPI, which was already clocked as slow as it can go, so I'd have to come up with an alternative SPI implementation.  Normally, the difficulty in this would be maximizing the potential clockspeed, but in this case that's not an issue and bit-banging the protocol seemed pretty easy.  It probably should have been, but I messed up some of the bit twiddling and I started to run into how much harder it is to debug firmware than it is to debug software running on your primary computer.

Anyway, I was eventually able to get it to work, though the programming was painfully slow (several minutes).  If you have the misfortune of getting stuck with a 128kHz ATmega, you can use my modified ArduinoISP code to rescue it.