Thursday, September 12, 2013

Complexity. Ambition. Progress.

What is the inclination many of us have to take on more than we can handle?

I have a really cool project I've been working on, that I'm not quite ready to reveal. It's turned out to be more ambitious that I originally thought, although I am making decent progress and achieving some things I doubted would be possible.

Is it that we overestimate our abilities, our speed, or that we have an inherent desire to avoid underachieving by aiming too low? My gut says.... well never mind what my gut says, it's always hungry, and rarely expresses anything appropriate for mixed company. My head says that we're simply just poor estimators, and there's probably tons of blogs and expert on the web that agree. What has really consumed a lot of the time on this project, were some of the mundane things that I didn't really consider, such as spending a week tracking down errors due improper CPU registers.

It seems that as some of my home hobby projects get more ambitious, and by definition more cool, I'm spending longer and long in between completed projects, with more time spent in the "this is going to be magical one day" phase. I definitely think after my current project I need a few short and sweet ones, to get that gratification of having achieved magic.


Wednesday, September 4, 2013

Really short sanity check list for vexing AVR anomalies.

I've been chasing down some bizarre behavior on an Atmega 1284 for the better part of a week.

I'm posting this so that I can print it out and tape it to my forehead for future reference.

When trying to determine the root cause of strange behavior in your code, you have to sometimes use a process of elimination. Sometimes, it's best to check the easiest possibilities first, regardless of how likely you may think any given cause is. My code was behaving in pseudo consistent ways, something would fail, repeatedly. I would add code to try and catch the error before thing went haywire. I was convinced I had a memory overwrite, or a stack overflow. As soon as I would add the code to catch a problem. It would start working, or stepping though the code would give a different result than running full speed.

Here is a list of things to check while your scratching your head: (In this order)

  1. Fuses. (This turned out to be my problem). I had my fuses set for an external RC oscillator, instead of a crystal. Fuses are so easy to check, it should be the first thing you do. Scrutinize each setting, read the datasheet for each one.
  2. Proper capacitors on the external crystal.
  3. Breadboard noise. I rebuilt my breadboard, it started working better, but not perfect, so I'd assumed it was noise and a memory clobber causing the issues.
  4. Proper JTAG connection. (JTAG seems more sensitive to noise than SPI/debug wire debugging). To eliminate this as a possible cause, program the flash with the "device programming tool" in AVR Studio, using the generate hex file, and use the verify feature. Write some diagnostic code to print to a serial port, then disconnect the JTAG. If your problems go away, it may have been the tool.
  5. Memory stomp. These are pretty common, and can be hard to pinpoint, in pointer arithmetic-heavy code. Stack overflows are particularly nasty and difficult to detect, set breakpoints at your "deepest" code paths, and look at the SP register in the debugger. Comment/stub out large local variables, and eliminate recursion.
  6. Compiler bugs

The last one is actually pretty rare, but it does happen. Odds are you will have found the problem before oyu get to that stage.