Reading Fuse and Lock Bits from Firmware

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I want to read the fuse bits while it is running.
At the moment, I'm using an ATtiny13.

I've read the section in the datasheet "Reading Fuse and Lock Bits from Firmware", but I can't get my inline assembly working.

This is how far I got (but it's not working):

  uint8_t data;

  // This is totally wrong.
  Z = 0x0000;
  SPMCSR |= (1 << RFLB);
  SPMCSR |= (1 << SELFPRGEN);
  data = __LPM_();          

  // But this is also wrong.
  asm volatile("ldi r30, 0\n\t"
               "ldi r31, 0\n\t"
               "sbi SPMCSR, RFLB\n\t"
               "sbi SPMCSR, SELFPRGEN\n\t"
               "lpm\n\t"
               "sts r0,data\n\t"
               ::);
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why use gobbledygook?

avr-gcc has functions for just this purpose.

Note that the A versions of the older chips seem to have some extra functionality.
The chips without bootloaders seem to have a SELPRGEN fuse. You need to set this fuse for SPM to work.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks!

I assumed that boot.h was only for chips with a boot sector, but it is also for the ATtiny13.

#include 
...
uint8_t data1,data2,data3,data4;

cli();
data1 = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS);
data2 = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
data3 = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS);
data4 = boot_lock_fuse_bits_get(GET_LOCK_BITS);
sei();

For my ATtiny13, the low fuse is 0x7A (correct for 9.6MHz), and the others read 0xFF.
The SELFPRGEN is not enabled, so that is not needed to read those bytes.

gobbledygook : http://en.wikipedia.org/wiki/Gob...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not sure if I have used the avr-gcc version for Tinys. I definitely have for Megas.
I know that I have written an equivalent for CodeVision, and used that for Tiny45, 85, 2313, 4313.
As far as I can remember, you have the odd name change to sort out with the preprocessor. ( probably saves you that grief)

I have not got a Tiny13.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, I got everything from . It even explains that interrupts should be off, since it is time critical.

avr boot.h: http://www.nongnu.org/avr-libc/u...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
For my ATtiny13, the low fuse is 0x7A (correct for 9.6MHz), and the others read 0xFF.

0xFF is not an unreasonable value for HFUSE or LOCK... (don't forget that "programmed" fuses become 0, so the default state, and value for unused bits, is going to be "1")

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll bite: While it may be interesting to read e.g. signature/model, and for completeness "why not" allow read of fuse/lock, of what practical purpose is it to have an AVR firmware read those bits? It is your app; you can write the firmware in the manner needed.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Judging by the number of posts here where people compile code inappropriate for their AVR, it would be a useful diagnostic.

OTOH, they often do not get as far as LCD or UART display. So it is unlikely that they can report the values anyway.

However it would catch those people who get so far, but have BOOTRST or DWEN set, or those with bootloaders but not set their lock bits.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
... of what practical purpose is it to have an AVR firmware read those bits ...

Well, I was trying to show info on a lcd. Like the compiler __DATE__ info, and the oscillator calibration value. I also was testing a software reset with the WatchDog timer. So I would like to know the delays and if the WatchDog was enabled. And I would like to be able to use inline assembly. So mainly it was a learning exercise.

What I learned:

The OSCCAL value of the ATtiny13 was not very accurate. I change it from 116 to 122 in small steps. The accuracy is now 3 seconds in 5 minutes too fast. Next step is to link it with the mains power 50Hz or 60Hz. For a clock a CTC timer of 300Hz is possible, and the rest is done in software.

The WatchDog timer keeps running after a (warm) reset, so that had to be turned off. But I still don't have it working as a reset.

Inline assembly is just too far fetched for me.

This is the clock ISR for the ATtiny13 (running at 9.6MHz, it's not possible to make 100Hz or 1Hz, but 300Hz is possible with timer in CTC mode):

ISR (TIM0_COMPA_vect)
{
  static uint8_t prescaler3, prescaler100;

  prescaler3++;
  if (prescaler3 >= 3)
  {
    prescaler3 = 0;
    // This the place for 100 Hz.
    prescaler100++;
    if (prescaler100 >= 100)
    {
      prescaler100 = 0;
      // This is the place for 1 Hz.
      seconds++;
      if (seconds >= 60)
      {
        seconds = 0;
        minutes++;
        if (minutes >= 60)
        {
          minutes = 0;
          hours++;
          if (hours >= 24)
          {
            hours = 0;
          }
        }
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Like the compiler __DATE__ info,

What does that have to do with fuse and lock bits?
Quote:

and the oscillator calibration value.

What does that have to do with fuse and lock bits?

Quote:

So I would like to know the delays and if the WatchDog was enabled.

What does that have to do with fuse and lock bits?
Quote:

And I would like to be able to use inline assembly.

What does that have to do with fuse and lock bits?

So, as I seem to be repeating myself, I'll do it once more:

Quote:

I'll bite: While it may be interesting to read e.g. signature/model, and for completeness "why not" allow read of fuse/lock, of what practical purpose is it to have an AVR firmware read those bits?

Quote:

(running at 9.6MHz, it's not possible to make 100Hz or 1Hz,

Let me think about that for a minute. To what accuracy? Why is 100Hz important for a RTC? why isn't 10Hz or 20Hz or 16Hz or whatever just as good?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To get a clock with the ATtiny13 at 9.6MHz and with a 8-bit timer hasn't got a lot posibilities. A timer in CTC mode can do 150 or 300 Hz. So if I also want a system tick of 100Hz, I had to use the 300Hz.

You ask a lot what it has to do with the fuse and lock bits. I was only explaining what I was doing, and reading the fuse and lock bits was part of it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
of what practical purpose is it to have an AVR firmware read those bits?

Well, for instance, I wrote an Arduino sketch that reads and pretty-prints fuse and lockbit settings. It's supposed to be for debugging strange user reports "why does my blink sketch seem to be running at half speed?" or "How come the bootloader only works once?" and similar.

A typical Arduino user doesn't have any other way to look at the fuse values.

Of course, the number of cases when the fuses are wrong, but still "ok" enough to run the sketch and report the results in visible form, is somewhat small...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

You ask a lot what it has to do with the fuse and lock bits.

What was the thread title?
What was the first sentence of the OP?

So, why would you >>think<< I'd try to replay your responses that supposedly relate to my query about the practical use to the thread title/topic.

I guess I'm out, not being able to think outside the box and all. See, being a confused old guy it is mysterious how an Arduino user who

Quote:
doesn't have any other way to look at the fuse values

could get mangled fuses in the first place.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.