[Icc-avr] Reading Fuses on Mega88
John Baraclough
j_baraclough at zetnet.co.uk
Thu Nov 29 09:08:14 PST 2007
The data sheet states that the fuse and lock bits can only be read
within three clock cycles of setting SPMCSR. After that reading is
disabled. This is even more restrictive than the four clock cycle
access to the watchdog timer which also catches out a lot of people.
Unfortunately C does not give you any means of accessing the Z
register directly before attempting to read the Flash. You might be
lucky and get it to work if you force 'ptr' to be in registers, use
an intermediate register variable and change the order of your code as follows:
void ReadFuseLock(void)
{
register const unsigned char* ptr;
register unsigned char temp;
unsigned char Fuse[4];
// Read lock bits
ptr = (const unsigned char*)(0x0001); // 0x0001 to read lock bits
SPMCSR = 0x09; // (BLBSET | SPMEN) to read fuse and lock bits
temp = *ptr;
Fuse[0] = temp;
// Read fuse low bits
ptr = (const unsigned char*)(0x0000);
SPMCSR = 0x09;
temp = *ptr;
Fuse[1] = temp;
// Read fuse high bits
ptr = (const unsigned char*)(0x0003);
SPMCSR = 0x09;
temp = *ptr;
Fuse[2] = temp;
// Read extended fuse bits
ptr = (const unsigned char*)(0x0002);
SPMCSR = 0x09;
temp = *ptr;
Fuse[2] = temp;
}
This code is untested and just an idea, so you'll need to compile it
and have a look at the list file to check the timings. You may find
that 'ptr' and 'temp' are allocated in registers anyway so you don't
need to declare them as such. If all that fails, then you'll have to
go to assembler as Richard says.
All the best for now,
John
At 11:31 29/11/2007, you wrote:
>Does anyone know how to read fuses on a mega88?
>
>I have tried the following but the results are incorrect.
>
>void ReadFuseLock(void)
>{
> const unsigned char* ptr;
> unsigned char Fuse[4];
>
> // Read lock bits
> SPMCSR = 0x09; // (BLBSET | SPMEN) to read fuse and lock bits
> ptr = (const unsigned char*)(0x0001); // 0x0001 to read lock bits
> Fuse[0]=*ptr;
>
> // Read fuse low bits
> SPMCSR = 0x09;
> ptr = (const unsigned char*)(0x0000);
> Fuse[1]=*ptr;
>
> // Read fuse high bits
> SPMCSR = 0x09;
> ptr = (const unsigned char*)(0x0003);
> Fuse[2]=*ptr;
> }
>
>The values returned are:
>
>Lock Bits 0xC0 (should be 0xFF)
>
>Fuse Low Bits 0x31 (should be 0xE6)
>
>Fuse High Bits 0xC4 (should be 0xD8)
>
>Any ideas anyone?
>
>Regards,
>
>Ian James
>--
>Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
>
>_______________________________________________
>Icc-avr mailing list
>Icc-avr at imagecraft.com
>http://dragonsgate.net/mailman/listinfo/icc-avr
More information about the Icc-avr
mailing list