All,
I just got nailed by a miss programmed (by me of course) M128 fuse. After spending a few
hours tracking down the problem, it occured to me that my application probably should
check for this kind of situation at startup and do something if things aren't right.
The code below is the first cut; it just reads and displays the current settings. It will
fail if the M128C fuse is programmed (haven't figured out the best way to detect that yet)
but otherwise works fine.
The code was written for the ICCAVR compiler but should be adaptable to others.
Bruce
---------------------------------------------------------------------------
struct M128_FUSES
{
unsigned cksel : 4; // low byte
unsigned sut : 2;
unsigned boden : 1;
unsigned bodlevel : 1;
unsigned bootrst : 1; // high byte
unsigned bootsz : 2;
unsigned eesave : 1;
unsigned ckopt : 1;
unsigned spien : 1;
unsigned jtagen : 1;
unsigned ocden : 1;
unsigned wdton : 1; // extension byte
unsigned m103c : 1;
unsigned unused : 6;
unsigned lb : 2; // lock bit byte
unsigned blb0 : 2;
unsigned blb1 : 2;
};
union FUSES
{
struct M128_FUSES f_bits;
unsigned long fuse_state;
} fuses;
unsigned long get_fuse(void) // get fuses to test clock source and stuff...
{
asm
(
"ldi r26, 9 ; BLBSET & SPMEN \n"
"mov r0, r26 ; to read fuses \n"
"ldi r26, 0x68 ; spmcsr \n"
"ldi r27, 0 \n"
"ldi r30, 0 ; start with FLB \n"
"ldi r31, 0 \n"
"st x, r0 ; prime the pump \n"
"lpm r16, z+ ; fuse low byte -> R16 \n"
"st x, r0 \n"
"lpm r19, z+ ; lock byte -> R19 \n"
"st x, r0 \n"
"lpm r18, z+ ; fuse ext byte -> R18 \n"
"st x, r0 \n"
"lpm r17, z ; fuse high byte -> R17 \n"
"ret \n"
);
return(0); // keep the compiler from whinning
}
void show_fuses(void) // display M128 fuses @ startup
{
fuses.fuse_state = get_fuse();
printf("\nProcessor Fuses:\n\n");
printf(" cksel = %1u sut = %1u boden = %1u bodlevel = %1u\n",
fuses.f_bits.cksel, fuses.f_bits.sut, fuses.f_bits.boden, fuses.f_bits.bodlevel);
printf("bootrst = %1u bootsz = %1u eesave = %1u ckopt = %1u\n",
fuses.f_bits.bootrst, fuses.f_bits.bootsz, fuses.f_bits.eesave, fuses.f_bits.ckopt);
printf(" spien = %1u jtagen = %1u ocden = %1u wdten = %1u\n",
fuses.f_bits.spien, fuses.f_bits.jtagen, fuses.f_bits.ocden, fuses.f_bits.wdton);
printf(" M103c = %1u lb = %1u blb0 = %1u blb1 = %1u\n",
fuses.f_bits.m103c, fuses.f_bits.lb, fuses.f_bits.blb0, fuses.f_bits.blb1);
}Message
Fuse detection
2004-06-10 by Bruce Parham
Attachments
- No local attachments were found for this message.