Optiboot for Tiny1634 + Tiny841

Update:
Tiny1643 optiboot contributed to rambo's 1634 core: GitHub - rambo/arduino-tiny at attiny1634

Tiny841 optiboot available with my 841 core: GitHub - SpenceKonde/arduino-tiny-841: Arduino core for ATtny841, 828, 1634 and 441

Does anyone know if anyone has made Optiboot work with the ATtiny1634? (I haven't had any luck searching)

If not, can anyone give me a big-picture outline of the general process of adding support for a new chip to optiboot?

It's a really sexy chip, quite frankly - 2 UARTs, 16k flash, 1k sram, 4 PWM outputs, 17 usable (ie, non-reset) pins in a cute little SOIC-20 package, hardware SPI - it looks more like a mega than a tiny. I got INPUT_PULLUP working on it last night (it doesn't use the same scheme as older AVRs). It cries out for a bootloader imo; I for one would love a cheap chip that I could program over serial, and still have a free real serial.

Not that I know of.

The attiny1634 doesn't support a separate boot section, meaning that you'd have to use optiboot's "virtual boot partition support", and ... I don't know if that actually works :frowning:

Other than that, it's like:

  • create a makefile entry based on the closest equivalent (flash-size-wise.)
  • try to compile.
  • Fix errors till it compiles.
  • Try it out
  • fix errors till it works.

Oh man - I hadn't noticed that it didn't have proper bootloader support. That's a bummer! Come on Atmel, why you gotta be like that?

I'll take a stab at it with virtual boot (probably after I either succeed or get frustrated and need a break from working on a Tiny841 core) and see if I can make it work.

How do I set up the build environment to compile it? It sounds like it can be built on windows, but windows doesn't have make, so I'm not really sure how that works (I've never built anything on windows other than arduino sketches). I have linux systems too, if it's easier to get the toolchain to work there. But either way, where can I get information on how to set that up?

How do I set up the build environment to compile it?

The easiest way is is to use an Ardunio 1.0.x IDE, which includes a full copy of "WinAVR", including utilities like "make."
if you put a copy of the optiboot source directory parallel to hardware/arduino/bootloaders/optiboot (new-optiboot), you can use the "omake" batch file for builds and it will use the tools included. See https://code.google.com/p/optiboot/wiki/CompilingOptiboot

Unfortunately, the 1.6 IDE does its own source-level build of tools, and only includes those actually used by the IDE, so it no longer has make, bash, or other unix-like tools, and this doesn't work any more (and isn't likely to ever work. :-()

Other alternatives include installing WinAVR itself (although this is abandoned and old), or downloading the Atmel tools.
There's also the Atmel "Toolchain for Windows", which is up-to-date and includes most of the tools that used to be in WinAVR: http://www.atmel.com/tools/atmelavrtoolchainforwindows.aspx (there's a similar download for linux, and many linux package managers will include a relatively recent version of avr-gcc as a package. Look for 4.8.1 or later. (avr-gcc version; the Atmel version number is completely different.)

Okay, 1.0.6 it is.

That's what I'm using anyway - posts mentioning advantages of 1.6 seem to be greatly outnumbered by posts bemoaning it's problems, so I figured 1.0.6 is what I wanted :wink:

Thanks for the help on this - I'll report back if I have any success, or well-defined questions.

I've looked into this a bit...

  1. -mshortcalls was removed in recent avr-gcc. I replace with -mrelax as recommended 54854 – [avr] Deprecate and finally remove the -mshort-calls command line option
    New compiler's optiboot is 4 bytes larger.

  2. -DVIRTUAL_BOOT does nothing as far as i can tell. Atmega328 and virboot328 create an identical .hex file.

  3. -DVIRTUAL_BOOT_PARTITION i think is what was meant. With this one, program size is considerably larger - 652 bytes. But at least it builds!

So (working with an atmega328, let's keep it simple) I flash the hex via ISP, and also set fuse to 0xD1 (ie, turned off reset vector , and try it out. Uploading works - I can read out the flash with eXtremeBurner, and i upload code, and data appears where it was previously blank - it even looks like the right amount of code too!

But the sketch doesn't ever run. It seems like the last step, leaving the bootloader and going to the sketch, isn't working.

Modified part of makefile:

# Test platforms
# Virtual boot block test
virboot328: TARGET = atmega328
virboot328: MCU_TARGET = atmega328p
virboot328: CFLAGS += $(COMMON_OPTIONS) '-DVIRTUAL_BOOT_PARTITION'
virboot328: AVR_FREQ ?= 16000000L
virboot328: LDSECTIONS  = -Wl,--section-start=.text=0x7d00 -Wl,--section-start=.version=0x7ffe
virboot328: $(PROGRAM)_atmega328.hex
virboot328: $(PROGRAM)_atmega328.lst

Any thoughts?

On a system with virtual boot, does the bootloader need to be 512 or 1024 bytes long, or was that enforced by the way the bootloader works on chips with native support, so I could make the end of the program end 1 page short of the bootloader (1634 flash pages are 16 words long, so that'd save a significant amount of space)?

Are you working with the optiboot sources from Google Code? I had already fixed the "-mshortcalls" issue, and there are a bunch of other changes there that may or may not be helpful.

-DVIRTUAL_BOOT does nothing [should be -DVIRTUAL_BOOT_PARTITION]

Oops. Confirmed.

652 bytes

Sounds about right. 596 bytes in the current source, but various stuff has been removed. Note that for a non-bootloader-supporting chip, the granularity of bootloader size is much finer (1 Flash Page, vs doubling via BOOTSZ)

https://code.google.com/p/optiboot/issues/detail?id=120

Apparently not - I was using one of the zips - I'm used to github, not google code.

I got the latest source, and am getting 596, like you (after fixing the makefile)

virboot328: TARGET = atmega328
virboot328: MCU_TARGET = atmega328p
virboot328: CFLAGS += $(COMMON_OPTIONS) '-DVIRTUAL_BOOT_PARTITION'
virboot328: AVR_FREQ ?= 16000000L
virboot328: LDSECTIONS = -Wl,--section-start=.text=0x7d00 -Wl,--section-start=.version=0x7ffe
virboot328: $(PROGRAM)_atmega328.hex
virboot328: $(PROGRAM)_atmega328.lst

But same behavior (except now the LED works, so you can confirm what it's doing). It just repeatedly goes through the bootloader.

the last step, leaving the bootloader and going to the sketch, isn't working.

I looked at this some more, and the whole vector replacement thing is wrong because the 328 has 4-byte vectors and "jmp" instructions, instead of 2-byte vectors and "rjmp" instructions. But it will be different on different chips :frowning: I need to look more closely to see if there's a way to generalize that code.
(1634 also has 4byte jmps in the vector table, so 328 fixes should work there as well.)
(It's the chips with 8k or less that can only have rjmp.)

In case it helps, I believe TCWORLD has Optiboot working for the t85 processor...

A useful reference, but full of the sort of hardwired constants that I'd like to avoid.
I'm working with something like:

#ifdef __AVR_HAVE_JMP_CALL__
// AVRs with more than 8k of flash have 4-byte vectors, and use jmp.
#define rstVect0 2
#define rstVect1 4
#define wdtVect0 (WDT_vect_num*4+2)
#define wdtVect1 (WDT_vect_num*4+3)
#define appstart_vec (WDT_vect_num*2)
#else
// AVRs with up to 8k of flash have 2-byte vectors, and use rjmp.
#define rstVect0 0
#define rstVect1 1
#define wdtVect0 (WDT_vect_num*2)
#define wdtVect1 (WDT_vect_num*2+1)
#define appstart_vec (WDT_vect_num)
#endif
#else
// AVRs with bootloader support don't need vector munging.
#define appstart_vec (0)
#endif

I'll send the complete file by PM. It's compiling, and I should be able to test VBP on 328/168, but I'm going away for the weekend, so you might get more done in parallel.

Hmm. It doesn't look like I can attach code to PMs.

optiboot.c (32 KB)

No dice - now once it gets code (blink) uploaded once, the LED flashes very rapidly (same behavior as you see with and it can't be reprogrammed except via ISP (and AVRdude complains about verification failure when I upload the sketch: "first mismatch at byte 0x0002 0x5c != 0x00" - not that i particularly care)

I'm a little fuzzy on what exactly is supposed to be happening here. I recognize that the first bunch of words in the flash are the interrupt vectors. 0x0000 is reset, and 0x000C (these are word addresses, i guess, so that means address 0x0018 by bytes) is the WDT interupt.

Straight up after programming, I can then read out the data via ISP, and see what the vectors are... but they're the same as they are after programming on a normal optiboot!

All except RESET are JMP to 0x006E (which itself appears to be JMP to 0x0000, ie, reset vector), except TIM0_OFV (millis), which is JMP to 0x0088, and reset is JMP 0x005C.

Wouldn't we need the reset vector pointing to the bootloader when we're using a virtual boot partition?
That starts at byte address 0x7D00, that's word address 3E80. Okay, so I change that and write it back - and sure enough, that makes it run the bootloader... but not the sketch. I guess what I'm unclear on is how control is ever supposed to get back to the.... That's what you're using the WDT vector for! So let's put 0x005C at word address 0x000C... and bootloader works, and sketch runs!

So we need the WDT vector to be what the reset vector originally was, and the reset vector pointing at the bootloader. Oh ya, that's what the comments say it's doing... so why isn't it...?

Aaah! After all this:
rst_vect1 should be 3, not 4.
need to test if address==0, not ==rst_vect0, since rst_vect0 is 2, but we'll be checking against the start address, which will be zero.

Badabingkapowie! It works! Now, to optimize the makefile a bit for the virboot328 to minimize wasted space, and then get to work on tiny1634!

Woohoo!

I've got it compiling for the 1634, but it doesn't work. It gives the 3-blink signal after burning bootloader - though the first few sets of flashes are not evenly spaced, which is strange. i don't know what that means. I tried to upload blink, and it wrote something to the flash.... but not the right thing, because now instead of blinking, we just get nothing.

We get a clue:

avrdude: verification error, first mismatch at byte 0x0000
0x0c != 0xff
avrdude: verification error; content mismatch

Unfortunately, my USBAsp doesn't work with the Tiny1634, leaving me without a way to read the flash, so I don't have a way to see what it did wrong. Is there a way to dump the flash with ArduinoAsISP (that seems to work)?

Changes made:

Added pin_def for tiny

Added to makefile for attiny1634, fix '328 virboot, set it to use as little flash as possible.

Fixed issues as described above in optiboot.c

The 1634 has TIFR, not TIFR0 and TIFR1, and requires you to write D8 to the CCP register to enable writes to WDE and WDP in WDTCSR, instead of WDCE in WDTCSR. I handled these with #defines

I think that's it?

Edit: FFS, why can't we attach .hex?

attiny1634: TARGET = attiny1634
attiny1634: MCU_TARGET = attiny1634
attiny1634: CFLAGS += $(COMMON_OPTIONS) '-DVIRTUAL_BOOT_PARTITION'
attiny1634: AVR_FREQ ?= 8000000L
attiny1634: LDSECTIONS  = -Wl,--section-start=.text=0x3c00 -Wl,--section-start=.version=0x3ffe
attiny1634: $(PROGRAM)_attiny1634.hex
attiny1634: $(PROGRAM)_attiny1634.lst


# Test platforms
# Virtual boot block test
virboot328: TARGET = atmega328
virboot328: MCU_TARGET = atmega328p
virboot328: CFLAGS += $(COMMON_OPTIONS) '-DVIRTUAL_BOOT_PARTITION'
virboot328: AVR_FREQ ?= 16000000L
virboot328: LDSECTIONS  = -Wl,--section-start=.text=0x7d80 -Wl,--section-start=.version=0x7ffe
virboot328: $(PROGRAM)_atmega328_virboot.hex
virboot328: $(PROGRAM)_atmega328_virboot.lst

optiboot_attiny1634.hex

:103C00001F92CDB7DEB7112485B715BE982F9D70D2
:103C100009F001D185E08093710082E086BD88E1E2
:103C200085BD86E084BD88E081BD8EE0E1D0409A0C
:103C300026E088E19EEF30E890936F0080936E005D
:103C400039BF09B607FEFDCF389AA8952150A1F7D4
:103C500080E09EE1D92E612C712C23E0C22EBB2482
:103C6000B39435E0A32E7C01BAD0813479F4B7D077
:103C70008983C2D08981823811F482E005C08138FD
:103C800011F486E001C083E0A5D0A1C0823411F414
:103C900084E103C0853419F485E0B6D098C0853539
:103CA00041F49DD0682E9BD0712C782A660C771C2D
:103CB0008DC0863521F484E0A7D080E0E5CF84363E
:103CC00009F04EC08CD08BD0982E89D0882E00E081
:103CD00011E085D0F80181938F019E12FACF8CD02C
:103CE00061147104C1F42091020120934401909168
:103CF00003019093450180911601809346018091C4
:103D00001701809347012093160190931701E092C9
:103D10000201D0920301F5E48F1201C0FFCFF3013D
:103D2000C7BEE89507B600FCFDCFA301A0E0B1E057
:103D30002C911296CD010197FC01808130E0382B47
:103D4000FA010901B7BEE89511244E5F5F4F9A1240
:103D5000EFCFF301A7BEE89507B600FCFDCF37C053
:103D6000843739F53CD03BD0982E39D045D08301EB
:103D7000960C0230110519F48091440114C00330EF
:103D8000110519F4809145010EC00631110519F491
:103D90008091460108C00731110519F4809147014F
:103DA00002C0F80184910F5F1F4F14D09012E1CF31
:103DB0000EC0853739F420D08EE10CD084E90AD0CA
:103DC00082E162CF813511F488E012D015D080E114
:103DD00001D04ACF06B405FEFDCF80BD089506B4DC
:103DE00007FEFDCF06B404FC01C0A89580B5089578
:103DF00098ED9FBD80BF0895F2DF803219F088E012
:103E0000F7DFFFCF84E1E6CFCF93C82FE8DFC150C3
:103E1000E9F7CF91F1CF282E80E0EADFEAE0FF2733
:023E2000099403
:023FFE000206B9
:0400000300003C00BD
:00000001FF

pin_defs.h (16.3 KB)

optiboot.c (32.3 KB)

Hmm hmm. Rst vector is at 0, but it's a 4-byte jump instruction with the target address (which is what we need to modify/move) starts at 2...

Flash dump shows the problem on tiny1634.

Root cause? 4 page erase. Well so much for shrinking the bootloader down to a multiple of the smallest page size. That small page size is just Atmel cheaping out, saving 96 bytes of page buffer u_u

:20000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:20002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
:20004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
:200060000C9462000C9462000C9462000C9462000180402010080402012010040201080435
:20008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:2000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
:2000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
:2000E0000E94FD0060E08DE00E94840168EE73E080E090E00C94FD00E1E7F0E08081887FD7
:20010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
:20012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF
:20014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
:20016000B11D209300018093010190930201A0930301B09304018091050190910601A091D3
:20018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F
:2001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F
:2001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F
:2001E0009A2F620F711D811D911D43E0660F771F881F991F4A95D1F70895CF92DF92EF92C7
:20020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
:20022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
:20024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE
:200260007C0083B1887F866083B91F9A0895CF93DF93C82FD0E0FE01E059FF4F3491FE018A
:20028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E
:2002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E
:2002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E
:2002E0002081232B20838881832B88835FBF09C09FB7F8948881822388838C91832B8C933E
:20030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD
:20032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD
:20034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD
:20036000B0E0FE01EC56FF4FC491D0E0922F909561110AC02FB7F8948C9189238C938881D4
:20038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
:2003A0000E9423010E9464000E946800FDCFF894FFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F
:2003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
:2003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D
:20040000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
:20042000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC
:20044000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC
:20046000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C
:20048000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C

Okay, I think I know what to do now...

Edit:

Got it working. Cleaning it up so it's more generic.

http://drazzy.com/e/optiboot_attiny1634.hex (ffs, why can't we attach .hex?)

Gonna try it on the 841 as well tonight (which has the 2-byte vectors, 4-page-erase).

Makefile

attiny1634: TARGET = attiny1634
attiny1634: MCU_TARGET = attiny1634
attiny1634: CFLAGS += $(COMMON_OPTIONS) '-DVIRTUAL_BOOT_PARTITION' '-DFOURPAGEERASE'
attiny1634: AVR_FREQ ?= 8000000L
attiny1634: LDSECTIONS  = -Wl,--section-start=.text=0x3c80 -Wl,--section-start=.version=0x3ffe
attiny1634: $(PROGRAM)_attiny1634.hex
attiny1634: $(PROGRAM)_attiny1634.lst


attiny841: TARGET = attiny841
attiny841: MCU_TARGET = attiny841
attiny841: CFLAGS += $(COMMON_OPTIONS) '-DVIRTUAL_BOOT_PARTITION' '-DFOURPAGEERASE'
attiny841: AVR_FREQ ?= 8000000L
attiny841: LDSECTIONS  = -Wl,--section-start=.text=0x1c80 -Wl,--section-start=.version=0x1ffe
attiny841: $(PROGRAM)_attiny841.hex
attiny841: $(PROGRAM)_attiny841.lst

(tiny841 still untested)

pin_defs.h (16.7 KB)

optiboot.c (32.4 KB)

Not having so much luck with the Tiny841.

It's clearly running - I get the three blink sign, and when I try to upload, I see it give another set of 3 flashes (indicating it's getting reset), but that's all that happens. I've doublechecked connections, and i've tried with UART0 and UART1. Any ideas on what i might look at on that?

Edit: Still nothing - I'm making zero progress.

I've got the chip rigged up with the DTR reset thing DTR to 0.1 cap to reset pin, 10k pullup on reset pin, and a diode between reset and Vcc to keep voltage on reset from going above 10k.

It definitely is doing something to the UARTs - when there's nothing connected to the serial pins, the led blinks continually, instead of in bursts of three (is it seeing line noise and thinking it's an attempt at starting communication?)

Also, every time the three-blink sign is shown when the FTDI serial adapter is connected, the RX led flashes once on the serial adapter.

Still trying to sort out what's going on with the tiny841. I'm wondering if it could be baud rate error...

I did this in getch(), and the LED stays on for a moment right as the upload tries to start:

  while(!(UART_SRA & _BV(RXC0)))
    ;
  if (!(UART_SRA & _BV(FE0))) {
  	  LED_PIN |= _BV(LED); //turn the light on
  	  for (;;){}    //and busy-wait until the watchdog forces reset
      /*
       * A Framing Error indicates (probably) that something is talking
       * to us at the wrong bit rate.  Assume that this is because it
       * expects to be talking to the application, and DON'T reset the
       * watchdog.  This should cause the bootloader to abort and run
       * the application "soon", if it keeps happening.  (Note that we
       * don't care that an invalid char is returned...)
       */
    watchdogReset();
  }
  
  ch = UART_UDR;
#endif

I backed off to 76800 baud, which should have lower error working off an 8mhz clock, and then all the way back to 9600 baud (with appropriate changes in boards.txt and restarting IDE after each change)- but no luck on that.

what's going on with the tiny841

Fuse values?

Did you fix/modify the code that recalculates the relative jump for the 2-byte vector?
That code was wrong (assumed a fixed relationship between wdt vector and reset vector), but I had only ifdef'ed it out while working on the 4-byte vector chips, rather than actually fixing it:

#if 0
        rstVect = vect;
        wdtVect = buff[8] | (buff[9]<<8);
        vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
        buff[8] = vect & 0xff;
        buff[9] = vect >> 8;
#else
        // Move RESET jmp target to WDT vector
        buff[wdtVect0] = rstVect0_sav;
        buff[wdtVect1] = rstVect1_sav;
#endif

I haven't gotten to the point of fixing recalculation of the reset vectors for parts with 2 byte vectors - I planned to cross that bridge when i came to it (I understand what needs to be done there) - but I haven't gotten there yet on the 841, since it's not responding to attempts to communicate over serial; as I mentioned, it appears to be getting a frame error.

My understanding is that if that was all that was wrong, it should write something you upload to it, just write it wrong, or at least get past the first handshake.

There may be an issue with the chip though - the extfuse is "stuck" at 00, and it resists all my attempts to write it - though other functionality seems to work, I can reprogram over SPI, etc. It's not exactly clear to me how this happened.

Fuses are supposed to be Low: E2, High:D7, Ext: FE.

Since that part is now suspect, I decided to make up another board - but I slipped during the reflow process, and the board is not salvagable (everything soldered down, but in the wrong places), and I've got no more '841's until the candyman (USPS) visits, probably friday.