Bootloader For ATmega 168 at 7.37 Mhz.

Hi all. I just acquired about 100+ small widgets (pics here: http://pics.umlautllama.com/?f=Projects/D15-ATmega ) They used to be stepper motor controllers for something here at work. They were plugged inline in a wiring harness. On one side power (+5v) as well as serial control via a D15, the other side is a 5 pin connector which the stepper motor used to plug into.

Long story short, I now have a D15-FTDI cable to hook this up for programming, and a D15-ICSP programming via Arduino (plug the two headers into a host Arduino, using the host to help program the D15 Widget. The only thing that I do not have is the firmware to drop onto these. They're just a standard ATmega 168, but they have a 7.37 MHz resonator on them, rather than an 8 or 16MHz one. I know this will require a tweak in the firmware, but I've not touched the firmware side of Arduino. (I've written raw firmwares for other devices, but never Arduino.)

Anyway, If someone can give me pointers as to how to start this; what tools i'll need, etc, to build the .HEX file (or whatever's appropriate), I'd be most appreciative. As far as I can tell, the only tweak needed for this will be adjustment of the speed. (Or, if one of you with this all set up already can make the tweak for me, that would work as well! I'll mail you a few of these things. :smiley:

The Arduino firmware only really works properly at 8MHz or 16 MHz. You should be able to get a pile of 8 MHz resonators at a reasonable price and replace the odd 7.37 MHz ones. If you don't make that change the serial I/O may be far enough out of spec that you can't use it.

You don't need to worry about a bootloader. Use an ISP device (under $10 on eBay for the USBasp) and connect it to the ICSP pins. Then you can use "Upload Using Programmer" in the File menu to upload your Arduino sketches. Depending on what pins connect to the stepper you might be able to use the standard Stepper library as-is.

Oh, interesting. I plan on hooking up an existing Arduino as the host for ICSP programming. Can I just download sketches through that to the target 7.3Mhz unit? Do i still need to shove the arduino bootloader onto that one, or is it just wasted space at that point?

I've worked at baremetal on other micros in the past, and I remember there being a lot of options to configure the various ports based on CPU speed to get desired bitrates out of it. I know that a stock 8mhz kernel won't work, since the baud rates will be all wrong, but as it currently runs, it talks via serial at 19,200, so I know that "standard" bitrates are possible with the crystal/resonator in it. I'm much better with software than hardware hacking, so digging in to the kernel and adjusting these things and rebuilding it once is a lot more appealing to me, rather than hacking around with surface-mounted resonators at $0.50-$1 each, for 100 units, and a few minutes per. :wink:

Actually, I just realized that I could probably also just switch it/reconfigure it to use the internal 8mhz clock generator... hrm

yorgle:
Do i still need to shove the arduino bootloader onto that one, or is it just wasted space at that point?

"Burning the bootloader" will set the fuse bytes. If you want to switch to the internal RC oscillator you will need to set the fuse bytes so "burning the bootloader" might be the easiest way.

One thing to worry about: the protection fuses MAY be set to prevent serial (ICSP) programming. If so you might need something like the High Voltage Rescue Shield to do parallel programming of the fuses.

Okay, so I was able to download the Arduino bootloader to my target device, using a second Arduino as a programmer, so I know this process works.

You had mentioned that I can use one of the other programmers to download sketches to it, rather than using the serial loader. Can I do this through the second Arduino set up as a programmer? There doesn't seem to be a configuration setting that covers this. It seems like the only thing that can be downloaded through a secondary arduino is the bootloader, or am I missing an option somewhere?

For what It's worth, I'm going to try to replace the 7.37 MHz crystal with a 16 Mhz model at some point. It's all surface mount, so it will likely be harrowing, but probably the best solution in the long run.

"You had mentioned that I can use one of the other programmers to download sketches to it, rather than using the serial loader. Can I do this through the second Arduino set up as a programmer?"
Yes - select File: Upload using programmer. The sketch is installed using the ICSP header.
That will override the bootloader and install the sketch so it immediately starts after a reset. The bootloader is no longer available after you do that.

If you still want a bootloader for 7.37MHz, it is actually fairly trivial to add an entry to the optiboot make file.

I have compiled one for you:
7.3728MHz (I am assuming it is this as it is the most likely standard crystal value - Baud rate crystal)
57600Baud

And the boards.txt entry:

##############################################################
atmega168f737.name=ATmega168 at 7372800Hz

atmega168f737.upload.protocol=arduino
atmega168f737.upload.maximum_size=14336
atmega168f737.upload.speed=57600

atmega168f737.bootloader.low_fuses=0xfd
atmega168f737.bootloader.high_fuses=0xdd
atmega168f737.bootloader.extended_fuses=0x04
atmega168f737.bootloader.path=optiboot
atmega168f737.bootloader.file=optiboot_atmega168_737.hex
atmega168f737.bootloader.unlock_bits=0x3F
atmega168f737.bootloader.lock_bits=0x0F

atmega168f737.build.mcu=atmega168
atmega168f737.build.f_cpu=7372800L
atmega168f737.build.core=arduino
atmega168f737.build.variant=standard

##############################################################

Just put the hex file under /bootloaders/optiboot/

optiboot_atmega168_737.hex (1.35 KB)

AWESOME! Thanks! I'd buy you a pint if I could! :smiley:

yorgle:
AWESOME! Thanks! I'd buy you a pint if I could! :smiley:

Just remember that millis(), delay(), micros(), and delayMicroseconds() won't be accurate for any clock rates except 8MHz and 16MHz. They rely on F_CPU/1,000,000 being divisible by 8. If you don't need accuracy in timing you'll be fine. :slight_smile:

micros() I think will be about 5% out due to this calculation:

#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )

millis() may be correct. It relies on the above calculation, but also another which may due to rounding cause the result to be the same as if FCPU=8MHz

delay() uses micros() so again it will be 5% out. For 1 second, you would use delay(949);

delayMicroseconds() will be completely wrong, but then really it isn't terribly good on the best of occasions, so nevermind.

EDIT:
Millis() will be about 5% out as well I think.