avrdudes / avr-libc

The AVR-LibC package provides a subset of the standard C library for AVR 8-bit RISC microcontrollers.
https://avrdudes.github.io/avr-libc/
Other
257 stars 56 forks source link

[bug #25929] boot.h Fuse read not compatible with Tiny48/88. #374

Closed avrs-admin closed 2 years ago

avrs-admin commented 2 years ago

Thu 19 Mar 2009 01:45:38 PM CET

boot_lock_fuse_bits_get() Assumes that BLBSET is defined.

In the Tinyx8 RLFB is used, not BLBSET:

SPMCSR – Store Program Memory Control and Status Register "Bit 3 – RFLB: Read Fuse and Lock Bits An LPM instruction within three cycles after RFLB and SELFPRGEN are set in the SPMCSR Register, will read either the Lock bits or the Fuse bits (depending on Z0 in the Z-pointer) into the destination register. See 'Reading the Fuse and Lock Bits from Software' on page 176 for details."

This issue was migrated from https://savannah.nongnu.org/bugs/?25929

avrs-admin commented 2 years ago

Frédéric Nadeau Wed 25 Mar 2009 01:58:14 PM CET

Problem is most likely not limited to ATtiny48/88. As far as I can tell it affect also: ATmega8/16HVA ATtiny13/13a ATtiny167 ATtiny2313 ATtiny43 ATtiny87 ATtiny24/44/84 ATtiny25/45/85 ATtiny261/461/861

The following seems to work. Might consider it as a temporary patch.

include <avr/io.h>

include <avr/boot.h>

define __READ_FUSE_LOCK_BIT_SET (_BV(__SPM_ENABLE) | _BV(RFLB))

define boot_lock_fuse_bits_get_tiny(address)              \

(extension({                                           \ uint8_t result;                                      \ asm volatile                                   \ (                                                      \ "ldi r30, %3\n\t"                                  \ "ldi r31, 0\n\t"                                   \ "sts %1, %2\n\t"                                   \ "lpm %0, Z\n\t"                                    \ : "=r" (result)                                  \ : "i" (_SFR_MEM_ADDR(SPM_REG)),                  \ "r" ((uint8_t)READ_FUSE_LOCK_BIT_SET),         \ "M" (address)                                    \ : "r0", "r30", "r31"                               \ );                                                     \ __result;                                              \ }))

I don't have the required chips to test the above, but it match the datasheet.