Confusion on TIFR Flags

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

Hello,

 

In doc2503 (ATmega32 Datasheet), page 83, the following is stated:

• Bit 1 – OCF0: Output Compare Flag 0
The OCF0 bit is set (one) when a compare match occurs between the Timer/Counter0 and the
data in OCR0 – Output Compare Register0. OCF0 is cleared by hardware when executing the
corresponding interrupt handling vector. Alternatively, OCF0 is cleared by writing a logic one to
the flag. When the I-bit in SREG, OCIE0 (Timer/Counter0 Compare Match Interrupt Enable), and
OCF0 are set (one), the Timer/Counter0 Compare Match Interrupt is executed.

Now, is this a typo or am I missing something? Also, a similar statement is present in the description of Bit 0 of this register as well. Thank you for your concern in advance.

 

Regards

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

It's not a typo.  The hardware can set and clear OCF0, as described.  It can also be cleared in software.  This is done with a single write, which is atomic, vs. a RMW, which is not atomic and thus open to a concurrency error.  The hardware could have been designed to take either a 1 or a 0 to clear the flag, but in the industry the use of a 1 for such flag-clearing is pretty much universal, and much more intuitive IMO.

 

The key thing to take away is that the write is atomic and thus safe.  A RMW cycle could encounter the following error:

 

MC = main code

HW = hardware compare match

 

MC: read TIFR

MC: clear OCF0 bit

HW: sets OCF0 bit

MC: writes out (incorrect) cleared OCF0 bit

 

Now a match has occurred but the flag is not set.  Error!

 

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

Thank you kk6gm but what I don't understand is how can a bit is set by writing 1 to it and cleared by again writing 1 to it? Or isn't this what the document states? If so, what am I missing here? Thanks again.

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

utku1 wrote:

Thank you kk6gm but what I don't understand is how can a bit is set by writing 1 to it and cleared by again writing 1 to it? Or isn't this what the document states? If so, what am I missing here? Thanks again.

Where does it say that the bit is set by writing a 1 to it?  The compare match generates a signal that causes the flip-flop representing the flag to be set to 1.  Writing a 1 to that bit generates a signal that causes the flip-flop to be set to 0.

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

It says it in the first bold region of my first post in this thread.

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

It says it in the first bold region of my first post in this thread.

No, it doesn't.  It says "cleared".

 

See very recent https://www.avrfreaks.net/forum/w...

 

 

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

utku1 wrote:

It says it in the first bold region of my first post in this thread.

No, it doesn't say that.  It says that a compare match causes the flag to be set to 1.

 

Think of a code equivalent of the underlying hardware:

 

if (compare_match)
  OCF0 = 1;
else if (compare_match_interrupt || (bit_is_written_to_flag && (bit_written == 1)))
  OCF0 = 0;

 

Last Edited: Sun. Oct 26, 2014 - 09:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's not a simple read-write register, which is likely a source of OP's confusion. It has two separate operations: get a copy of flags, and selectively clear flags (and leave the others alone). The first is mapped to a read, the second to a write. And they just happen to share the same address, since it would be a waste otherwise.
 

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

what I don't understand is how can a bit is set by writing 1 to it and cleared by again writing 1 to it?

...

compare match causes the flag to be set to 1

Only an interrupt event can set the flag to 1.

You cannot.

 

If the flag = 0

then either code

setbit(flag)

or

clrbit(flag)

has no effect

 

If the flag = 1 (caused by interrupt event)

then

setbit(flag) clears the flag to 0 (you will have to live with this)

clrbit(flag) has no effect

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

I think it is more clear now. Thanks everybody.

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

One more thing:

if (compare_match)
  OCF0 = 1;
else if (compare_match_interrupt || (bit_is_written_to_flag && (bit_written == 1)))
  OCF0 = 0;

So, when I write 1 to OCF0, what actually happens is OCF0 = 0. Is that true?

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

You can prove it yourself by writing some test code and running it in the simulator. 

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

Yes.

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

utku1 wrote:

One more thing:

if (compare_match)
  OCF0 = 1;
else if (compare_match_interrupt || (bit_is_written_to_flag && (bit_written == 1)))
  OCF0 = 0;

So, when I write 1 to OCF0, what actually happens is OCF0 = 0. Is that true?

Yes, the hardware for that register is designed so that writing a 1 sets OCF0 to 0, while writing a 0 has no effect.

Last Edited: Mon. Oct 27, 2014 - 06:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK. Thanks a lot again.

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

OK. Thanks a lot again.

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

OK. Thanks a lot again.

Someone earlier said:

Alternatively, OCF0 is cleared by writing a logic one to the flag.

Oh, wait--that was >>you<< in your original post.  Is there confusion that "cleared" means a 0 value, and "set" is a 1 value?

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

I guess not. "Cleared" and "set" states of the flag is just as the conventional "cleared" and "set" states of any bit as far as I understood. Only different part is, the flag is cleared by writing a logic 1 to it.