Flag checking in if-statement is setting flag? Xtiny1614 how to check if flag is set

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

I have been attempting to manually check for a compare interrupt flag in an if-statement but i

am only succeeding in setting whichever bit i am attempting to check and then also making the conditional true.

Which it then proceeds run the code in the if statement. (1<<0) was just confirming to me that indeed i am just setting flag bits.

I assume i can store the flag register in temporary variable to compare against.

   if(TCA0.SINGLE.INTFLAGS & (1<<0)){
    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP0_bm;// Clears flag
    TCA0.SINGLE.CMP0 += THIRTY2_MS;
    longCounter++;
    led_flash_counter++;
    led_low_PWR_count++;
   }

 

~William

Last Edited: Thu. Jun 21, 2018 - 07:06 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The flag you are checking is not the Compare Channel 0 Interrupt Flag but the Overflow / Underflow Interrupt Flag.
It must be correct below.

 

if(TCA0.SINGLE.INTFLAGS & TCA_SINGLE_CMP0_bm){
    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP0_bm;// Clears flag

 

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

I should have been more direct and not share about testing other bits than the CMP0 flag. Im burning the midnight oil (currently 3:30am here in MI-USA).

I will keep testing. Using an Atmel ICE to debug my code on the chip and i was appearing to be toggling the CMP0 bit by

using the if statement conditional. I should look at the disassembly code as well (super beginner there) befor jumping to a 

conclusion i know does not make sense, like an if statement compare possibly setting a bit.

~William

Last Edited: Thu. Jun 21, 2018 - 07:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The program code can not set the bit of INTFLAGS.
Writing a 1 to any bit in TCA0.SINGLE.INTFLAGS is an act of clearing that bit (to 0).

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

If you want "fast access" flag bits for "personal" use see if the chip has GPIORn registers. If it's really based on the Xmega you may find 16 of them in range of SBI/CBI

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

kabasan wrote:

The program code can not set the bit of INTFLAGS.

 

It appears the compare flag was being correctly set by the compare value match.

It was an incorrect thought and after three late nights i just started thinking anything is possible.

 

Using an Atmel Ice for the first time for on-chip debugging instead of only the simulator.

Things move alot faster.

One problem i found last night thanks to the ICE is this syntax error:

PORTB.OUTCLR |= PIN1_bm; // Instead of PORTB.OUTCLR = PIN1_bm;

*|= toggled all the ports that were set as outputs.

My next step is alot of break points for where im getting stuck.

Thanks everyone for all your input.

~William

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

Read the data sheet carefully.

|= PIN1_bm first reads PORT.OUT.
Then set bit 1 of the read bit field and write it back to PORT.OUTCLR.
The result is that all bits currently outputting High are also cleared and PORTB.OUT is all Low.

Is that what you want?

 

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

Hey Kabasan, With my problem I have found  a compiler optimization bug.

 

I have TCA0 compare channels: CMP0 set to 256 and CMP1 set to 39. TCA0 is clocked at 7812.5 hz, nice and slow.

When the chip is booted up it sets up the chip including initial compare values, then enters sleep mode.

A pin change interrupt wakes out of the power down sleep mode.

Once my sleep_cycle function exits:

The code jumps immediately to TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP1_bm;/*writing 1 to flag clears avr flags*/

In this if statement conditional in my main loop code:

*EDIT had to swap THIRTY2_MS with FIVE_MS, still is the same code jump problem.

if(TCA0.SINGLE.INTFLAGS & TCA_SINGLE_CMP1_bm){//5ms compare match
         TCA0.SINGLE.CMP1 += FIVE_MS;// resets/adds 5ms to counter compare
         TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP1_bm;/*writing 1 to flag clears avr flags*/
         buttonsPressed();
                   }

It jumps to it without even checking the conditional or starting anywhere near that code and the compare match never occurs within hardware the first time around, it just counts past

39 willie nilly and never sets the flag the first time around.

This is with optimization set for size (-Os)

When i turn optimizations off the code does not jump into that if_statement and the COMP1 match triggers the compare flag when the counter reaches 39-40.

Super weird!

~William

Last Edited: Fri. Jun 22, 2018 - 04:12 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If it is set to -Os, the breakpoint may be in an unexpected position.

This is because optimization may cause the order of instructions different from the source.
Is normal operation (state without debugging) different from what you expect?

If the behavior depends on the -Os setting or other, it is a possibility of a bug.

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

I have set up debugging for no optimizations for more readable debugging.

Although  what i observed was very odd, i have now discovered another/ the bug in my code.

 

There is a while loop that is pushing time/clocks well past my  "every 5ms" CMP1 compare match being flagged.

So CMP1 flag is being checked via the if_statement well after (>39 TCA0 clocks in this case)the Counter value matched the compare value, so when CMP1 += FIVE_MS;

: It is updating a Compare match value that is lower than the Counter value (after a certain part of my code), which is also a 16bit counter that has to count back around to compare!

Its about 8seconds to over-flow and check if the CMP1 flag was set.

Found that bug, gonna kill it with fire.

I swapped code from another chip to this one, along with learning Atmega > Xmega . I am comparing the old chips code to this one and its baffling why i did not have this problem before.

 

Thanks for your help.

~William

Last Edited: Fri. Jun 22, 2018 - 05:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can not solve even using double buffer?

That problem will be in the algorithm, not in the program.

Why do you need a wiggle compare match during one period?

Last Edited: Fri. Jun 22, 2018 - 06:38 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kabasan wrote:
If the behavior depends on the -Os setting or other, it is a possibility of a bug.

I'd say it's a high likelihood!

 

It almost certainly means that your code is making some unjustified assumptions.

 

https://www.avrfreaks.net/forum/shortcuts-taken-optimized-code-may-occasionally-sic-be-surprising

 

See also: https://www.avrfreaks.net/forum/tutcoptimization-and-importance-volatile-gcc

 

vertamps wrote:
I have set up debugging for no optimizations for more readable debugging.

Have you tried -Og ? It is specifically designed to give, "a better debugging experience"

 

 

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well it is a story of possibility.
He is currently confused with the tracing result at this stage and has not yet answered whether it is different from the expected move.
Let's think about whether to make noise about GCC after receiving the answer.

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

If it looks like a compiler bug can you try -Og and also give us a dump of the assembly code produced (in the .lst file)? You can also open a disassembly window in the debugger and step through one instruction at a time. It should be easy to see if the value is being read and compared.

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

mojo-chan wrote:

 try -Og

 

-Og compiled and running does not jump into my if_statement. I can manually adjust the Counter for a compare match, flag gets set and then code works as it should.

-O1,2,3,s all improperly jump to that line.

 

Even though it jumps into that part of code it appears to be only at the first boot up. In the grand scheme of things the function of the chip and program is unharmed by this.

I had taken a break after fixing my final bug in the code so im late to reply.

 

~William

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

vertamps wrote:

mojo-chan wrote:

 try -Og

and mojo-chan also wrote:
and also give us a dump of the assembly code produced 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

*EDIT, iv decided to remove the (massive) assembly code and will provide a stripped down version of the program if the same behavior will occur.

~William

Last Edited: Thu. Jun 28, 2018 - 04:11 AM