Fuses Teensyduino sets for Teensy 2.0

Status
Not open for further replies.

teckel

Member
What does Teensyduino set for the fuses on the Teensy 2.0? Specifically, the low fuses used to set the clock speed. The boards.txt file only sets F_CPU, so it seems that Teensyduino must be looking at the CPU speed and then setting the fuses correctly. I'm curious because looking at the ATmega32U4 fuses and datasheet, I can't figure out how the clock speed is able to be set to 2 MHz and 4 MHz. 1 MHz, 8 MHz, and 16 MHz I understand, but how is 2 MHz and 4 MHz selected when the crystal is 16 MHz?

I'm also interested in the startup time you set for power-down and reset. It seems the Teensy boots much faster than say an Uno, which must have to do with the startup time fuse settings. My guess is that the Uno goes with safe settings (16k CK/14 CK + 65ms) but the Teensy uses a much shorter startup time fuse settings.

I guess what I'd like to know is what Teensyduino sets for the fuse settings for the different menu options in the Arduino IDE. I'm trying to move a Teensy 2.0 project to a bare 328P and trying to create similar characteristics.

As always, thanks for this wonderful platform and support!

Tim
 
Do NOT attempt to change the fuses. If you connect an ISP programmer, you'll almost certainly destroy the bootloader. PJRC doesn't distribute that code, so this effectively ruins the board.

I always say that first, because it's so important. Again, DO NOT ATTEMPT TO CHANGE THE FUSES. I know you're doing something else... but for anyone who finds this thread looking for Teensy's fuse setting info, this warning is important. Don't connect an ISP programmer, as it will only cause a lot of grief.

The fuses CPU speed setting is merely an initial value for the clock prescaler. You can easily change the clock speed at the beginning of your program. There's no need to change the fuses. The fuses cause the CPU speed to start at 2 MHz, which allows Teensy 2.0 to boot up and run at lower voltages where 16 MHz isn't officially supported (but probably works anyway). Every C language example PJRC distributes, as well as every program built with Teensyduino, configures the CPU speed at startup, so the value in the fuses is only used for a very brief moment as the chip boots up.

Now, with all that warning and disclaimer stuff out of the way, here's the fuse settings used on Teensy 2.0:

Code:
#define FUSE_MSB        0b11011111    // pg 350, bootloader, 512 bytes, using HWB
#define FUSE_LSB        0b01011111    // pg 350, pg29 (8-16 MHz xtal), pg 31
#define FUSE_EXT        0b11110100    // pg 349, pg 51 (2.4V), HWB enabled
#define LOCK_BITS       0b11001100    // protected

Regarding this question....

The boards.txt file only sets F_CPU, so it seems that Teensyduino must be looking at the CPU speed and then setting the fuses correctly.

Actually, boards.txt has several lines that populate the Tools > CPU Speed menu, and cause your selection from that menu to set F_CPU. So it can be 16, 8, 4, 2, or 1 MHz, depending on whatever you select from that menu.

Inside the code, in hardware/teensy/cores/teensy/pins_teensy.c, the CPU speed is configure with this:

Code:
void _init_Teensyduino_internal_(void)
{
        cli();
        CLKPR = 0x80;
        CLKPR = CPU_PRESCALER;

The value for CPU_PRESCALER is defined in wiring_private.h:

Code:
#if F_CPU == 16000000L
#define ADC_PRESCALER 0x07
#define CPU_PRESCALER 0x00
#elif F_CPU == 8000000L
#define ADC_PRESCALER 0x06
#define CPU_PRESCALER 0x01
#elif F_CPU == 4000000L
#define ADC_PRESCALER 0x05
#define CPU_PRESCALER 0x02
#elif F_CPU == 2000000L
#define ADC_PRESCALER 0x04
#define CPU_PRESCALER 0x03
#elif F_CPU == 1000000L
#define ADC_PRESCALER 0x03
#define CPU_PRESCALER 0x04
#else
#error "Teensyduino only supports 16, 8, 4, 2, 1 MHz.  Please edit boards.txt"
#endif

If you're writing your own program, you probably can just hard-code the value you need.
 
Very informative, and a quick reply as always!

So, with Teensy you are setting the CPU speed in code only, not by changing fuses. I had figured you needed to change the fuses to change the speed. To do something similar with a bare ATmega328 I guess I would need to program a cpu_prescaler similar as you have done in Teensy. Having the CPU speed menu selection with Teensy has spoiled me.

I have only one other question. You mention that it's only running at 2 MHz for a short time. Looking at your fuse settings, this makes total sense. There's a 16 MHz crystal and you have the divide clock by 8 fuse bit set. So, it's running at 2 MHz. My question is if the fuses are set this way, how does it then run at a higher speed? Basically, fuses say it's 16 / 8 = 2 Mhz, yet the sketch can still run at 16, 8, or other speeds? How is this possible? Surely, if the crystal is 16 MHz and the fuse bit says to divide by 8 you can't just set F_CPU at the top of your sketch and it will change the speed, can you? I would think fuse settings would limit it to 2 MHz always. How is this the divide by 8 fuse bit turned off? Or, why doesn't it need to be turned off? Very confused by this.

Thanks again!

Tim Eckel
 
So, it's running at 2 MHz. My question is if the fuses are set this way, how does it then run at a higher speed? Basically, fuses say it's 16 / 8 = 2 Mhz, yet the sketch can still run at 16, 8, or other speeds?

The fuses CPU speed setting is merely an initial value for the clock prescaler. You can easily change the clock speed at the beginning of your program. There's no need to change the fuses.

This applies to Teensy 2.0 and Teensy++ 2.0. It may or may not apply to other boards or other AVR chips?
 
I'd like to suggest that the fuse bit settings put on the web site with the existing description of the bootloader. It took quite a bit of digging to find this fuse info.
 
Status
Not open for further replies.
Back
Top