[Icc-avr] Reading Fuses on Mega88
Johannes Assenbaum
jassenbaum at htp-tel.de
Thu Nov 29 15:05:15 PST 2007
Sorry, must be
//...
unsigned char readfusesbyte(unsigned int ioaddr, unsigned int fuseaddr);
//...
of course.
Best regards,
Johannes
---------------
The problem is, that const values must be in Z-pointer, i.e. R31:R30, and that LPM instruction must be executed in time. C may allow a solution, but it's hard job, so I prefer asm like this:
<file avrreadfusesbyte.s>
; unsigned char readfusebyte(unsigned int ioaddr, unsigned int fuseaddr);
;
_readfusesbyte::
movw r26,r16 ; load X-pointer with ioaddr
movw r30,r18 ; load Z-pointer with fuseaddr
clr r18 ; clear interrupts-enabled flag
brid readfusesbyte1
ldi r18,1 ; set interrupts-enabled flag
cli ; disable interrupts
readfusesbyte1:
ldi r16,0x09 ; bit names change but not the values. Yet...
st X,r16 ; write SPM control register
lpm r16,Z ; read fuses
sbrc r18,0
sei ; re-enable interrupts if enabled before
ret
</file avrreadfusebyte.s>
Add file to project and in C then write:
//...
unsigned char readfusebyte(unsigned int fuseaddr);
//...
void ReadFuseLock(void)
{
unsigned char Fuse[4];
// Read lock bits
Fuse[0] = readfusesbyte(SPMCSR,0x0001);
// Read low fuses bits
Fuse[1] = readfusesbyte(SPMCSR,0x0000);
// Read high fuses bits
Fuse[2] = readfusesbyte(SPMCSR,0x0003);
// Read extended fuses bits
Fuse[3] = readfusesbyte(SPMCSR,0x0002);
// and so on
}
Best regards,
Johannes
> 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
> _______________________________________________
> Icc-avr mailing list
> Icc-avr at imagecraft.com
> http://dragonsgate.net/mailman/listinfo/icc-avr
> --
> No virus found in this incoming message.
> Checked by AVG Free Edition.
> Version: 7.5.503 / Virus Database: 269.16.10/1159 - Release Date: 29.11.07 11:10
More information about the Icc-avr
mailing list