[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