if statement not picking up on variable change

Go To Last Post
124 posts / 0 new

Pages

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

It would be interesting to try the same tests with GCC.

 

I'm trying to come up with a test to determine exactly where the problem lies. The hierarchy, with CVAVR, from top to bottom is...

 

C Code -> Compiler -> ASM Output -> AVRASM -> .hex file -> xmega32E5

 

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

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

 

Well I got the stimulus file working in Studio & Simulator. It wasn't really that hard. I didn't realise Studio could open the COF debug format file either so I can debug Jim's exact code properly.

 

Here's the .stim file to inject the character 'J' into the RX pin: (The # lines are actually cycle delays)

PORTC.IN |= 0b00000100
#999
// Send 'J' 0x50 0b01010000
PORTC.IN &= 0b11111011
#87
PORTC.IN |= 0b00000100
#17
PORTC.IN &= 0b11111011
#17
PORTC.IN |= 0b00000100
#18
PORTC.IN &= 0b11111011
#17
PORTC.IN |= 0b00000100
#999

 

And the result:

Well the code as compiled by Jim works on the simulator. I get a USART ISR and I can see my 'J' sitting there in the USARTC0.DATA. I can single step through getchar() and putchar() and see my character get written out to the USART.

 

 

Last Edited: Sun. Mar 15, 2020 - 06:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A little more of an update.....

 

I am starting to wonder if the debugger is causing some of this.  I put a 'delay loop' using timer ticks at the beginning of the program.  In a debugging session the loop seems to be skipped, but if I run teh app on teh chip without the debugger it looks like it's there.  I have to wiggle a pin and use my logic analyser to confirm this.

 

Will post information once I try it.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

jgmdesign wrote:
In a debugging session the loop seems to be skipped

How do you determine that?

 

There's an option to allow timers to continue to run during a debugger 'break'.

If that's happening, and you're single-stepping, the timer could well have expired during a "step" - so it seems like the wait loop has been skipped ... ?

 

 

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

My Xmega32E5-XPLD board arrived on Monday.

 

Sure enough.   Jim's UART Codevision code did not work on the 32E5.

But Brian's addition of a single NOP made it work.

The code works fine on a 32A4U chip (with or without a NOP)

 

I am gobsmacked.   I wrote a similar AS7.0 project using the AVR1307 App Note

It works fine with CV or GCC.    However the DATAAVAILABLE() function has a larger calling overhead cost than simple inspecting a RX_Counter variable.

 

So I adjusted the ISR() and the getch() function for a RX_Counter variable.

CV worked for 32A4U

CV failed for 32E5

GCC worked for 32A4U

GCC worked for 32E5

 

If I add the NOP,  CV works for 32E5

 

I diff-ed the generated ASM and  S files.

Codevision compiles into exactly the same ASM code for 32E5 as for 32A4U.    The interrupt vectors are different.  The USART registers have different addresses.

Likewise GCC compiles into exactly the same S files.

 

It is a complete mystery.  32A4U and 32E5 have the same internal Core.   I would expect them to behave the same.

 

It is pretty straightforward to use the AVR1307 driver:

Adjust buffer sizes in the H file

Adjust BAUD,  Clock speed in the Example file

 

I attach an AS7.0 solution.   All 4 projects share the same source code.   Set F_CPU in Project Symbols for GCC or in CV Project Configure.

 

David.

Attachment(s): 

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

david.prentice wrote:

It is a complete mystery.

 

I need to add where I am on this.

 

With a couple of tweaks to the code, to stop destination addresses of calls and jumps changing, I can generate IDENTICAL .hex files, except for the section in main() where the test and branch take place. One of which works, one of which doesn't.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

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

Since the chips I am using are from my stores and are at least three years old, and Davids new board should have a 'new' chip on it, would it be safe to say that it's not an issue with the silicon?  I see documentation on the Mchip site is becoming hit or miss, otherwise I would take Lee's jab at looking for erratas.

 

JIm

 

 

 

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

My XPLD board was made in 2017.   The pcb was designed in 2012 !

 

The previous solution uses the AVR1307 scheme i.e. RXC and DRE interrupts

I have written another project.   This time using the CV Wizard scheme i.e. with RXC and TXC interrupts

 

There are several ways to handle USART interrupts e.g. with TXC, DRE or both.    Since CV and GCC both perform 100% "with the NOP" it means that the interrupts are working ok.  

The only difference is down to the foreground code.

 

The GCC loop is:

        if (DATAAVAILABLE()) {
00000113  LDS R24,0x2020		Load direct from data space 
00000115  TST R24		Test for Zero or Minus 
00000116  BREQ PC+0x05		Branch if equal 
            putch(getch());
00000117  CALL 0x000000AC		Call subroutine 
00000119  CALL 0x00000075		Call subroutine 
        nop();  //CV works with this NOP
0000011B  NOP 		No operation 
    }
0000011C  RJMP PC-0x0009		Relative jump 

and the CV loop is

        if (DATAAVAILABLE()) {
000001C3  LDS R30,0x2425		Load direct from data space 
000001C5  CPI R30,0x00		Compare with immediate 
000001C6  BREQ PC+0x04		Branch if equal 
            putch(getch());
000001C7  RCALL PC-0x00C0		Relative call subroutine 
000001C8  MOV R26,R30		Copy register 
000001C9  RCALL PC-0x00FD		Relative call subroutine 
        nop();  //CV works with this NOP
000001CA  NOP 		No operation 
000001CB  RJMP PC-0x0008		Relative jump 

So I find it difficult to see what the difference might be "without the NOP".    The only thing is CPI instead of TST but I can't see why this would matter.

 

I have added the two new projects to the ZIP.   (and deleted the monster DBG files from the ZIP)

Codevision produces a lot of "files" but does not remove all of them with "clean"

 

David.

Attachment(s): 

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

Have anyone look into the test I suggested in #83 ?

 

 I fear that :

 

LDS R30,0x2425		Load direct from data space

done at at a specific time of the TX will mess up some of the HW flags.

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

david.prentice wrote:
So I find it difficult to see what the difference might be "without the NOP".    The only thing is CPI instead of TST but I can't see why this would matter.
They have different effects on SREG, not that that should matter.

@sparrow2 Likewise LDS should only affect the target register.

Iluvatar is the better part of Valar.

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

Ok I expected that 

LDS R30,0x2425

was reading a IO 

 

If it's just a variable we really need to see how the data got there an when. 

 

add:

This is not to solve it but getting closer to what the real problem is.

 

Remember that some IO reads actually clear/change HW flags.

Last Edited: Thu. Mar 19, 2020 - 03:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The 0x2020 or 0x2425 is simply the global rx_counter_usartc0.

Yes it is incremented by the RXC interrupt and decremented by the User getch().   But getch() does it atomically.

 

LDS, CPI, BREQ should be no different to LDS, TST, BREQ.   It is only the Z flag that is used by BREQ.

 

The LDS is done from the foreground.   It is an uint8_t so is an atomic read.

If an RXC interrupt appears after the LDS it just means that it goes around the loop again.

 

But the same would apply to the GCC compiled version.   Or to the CV version for an A4U target chip.

 

If there is a Silicon "feature" I would expect it to appear with GCC too.

If it was a CV "feature" I would expect E5 and A4U to exhibit the same feature.

Any flag, register ... altered by an ISR() would crash both NOP and no-NOP loops.

 

David.

Last Edited: Thu. Mar 19, 2020 - 03:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So no one want to check if an other BAUD-rate change anything :(

 

 

add:

This is not to solve it but getting closer to what the real problem is.

 

Remember that some IO reads actually clear/change HW flags.

Last Edited: Thu. Mar 19, 2020 - 03:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can change BAUD from 110 to 115200 with F_CPU from 2MHz to 32MHz.   It makes no difference.

I would expect the new 32E5 chip to behave like my 32A4U chip i.e. correctly.

 

David.

 

Edit.   It is fun watching a 32MHz Xmega send text at 110 baud.

Last Edited: Thu. Mar 19, 2020 - 03:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

david.prentice wrote:
It is fun watching a 32MHz Xmega send text at 110 baud.

"Fun" was watching my 1st computer running at 1MHz sending/receiving text (via phone modem) at 110 baud.

(It was also "fun" when about a month later I was able to double processor speed to 2MHz and modem speed to 300 baud...)

 

Now, it pains me to be stuck with a (slow!) 1GHz Enet connection...

David (aka frog_jr)

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

In these work from time I will add:

my first computer "job" (about 1980) was to rewrite a commodore PET basic program so it reliable could RX/TX 300 BAUD. 

It was for an accountant that wanted to be able to work from home :)  

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

In the summer of 1980 I would've been using Commodore PET BASIC to control RF test gear using its HPIB (aka GPIB; nowadays IEEE 488) ...

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

awneil wrote:

In the summer of 1980 I would've been using Commodore PET BASIC to control RF test gear using its HPIB (aka GPIB; nowadays IEEE 488) ...

I too was doing something similar with an HP Basic desktop w/ HPIP, testing seismic gear performance after being repaired before returning the gear to the field crews. They working hard in order to find $30/barrel oil back then!

Got laid off when oil dropped to $15/barrel.....  it was fun while it lasted.

 

Jim

 

 

 

 

 

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

Jim I'm thinking that if your code was a real life app with anything more than just "that line" you would have never had any problems.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Thu. Mar 19, 2020 - 09:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:

Jim I'm thinking that if your code was a real life app with anything more than just "that line" you would have never had any problems.

 

I am thinking along the same lines, and the app itself does have stuff after it and has been running without much fuss with the debugging going on.  I am somewhat relieved/honored that David was able to replicate the issue I am having/had, so it's not some silly coding violation on my part.

 

Not abandoning teh fight on this, but for now taking a backseat as I need to get a project further along.

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

The cv generated code leaves the rx isr with its last instruction as a pointer type instruction (cv uses these in prologue/epilogue, where gcc uses push/pop). Your main loop has a single memory op of lds (and its target reg happens to be a pointer reg also). Maybe there is some internal 'hangup' after the isr reti that causes the lds to fail because of the pointer use (Y), and the nop happens to fix it for some reason.

 

It would be curious to know if other instructions besides nop fix it (like a lds r16,0x00, sei, whatever), or somehow change the lds r30 to use a non-pointer register, or get somehow get a nop inserted just before the reti, and so on. Would be odd that there would be any interaction problem such as this, but that code may also be quite unique.

 

If it was a problem as described above, one could create a simple test with asm and you would think it could be duplicated (on that avr anyway)-

 

#include <avr/io.h>

void test(); //asm code

int main(void) {

    //let tcc4 irq every 60 clocks
    TCC4.INTCTRLA = 1; //intlvl=low
    TCC4.PER = 60;     //give enough time to run through isr
    TCC4.CTRLA = 1;    //div1
    PMIC.CTRL = 1;     //lolvlen
    asm("sei");
    test();
}

 

;test.S

;isr increments rx_count

;main loop calls the dec_count when it sees rx_count is not 0

 

.set SREG, 0x3f
.set rx_count, 0x2000 ;first ram address

 

.global __vector_12 ;tcc4 ovf

__vector_12:
st -Y,r30 ;similar prologue style as cv
in r30,SREG
st -Y,R30

 

ldi r30,1
sts 0x80C,r30 ;intflags ovfif
lds r30,rx_count
subi r30,-1
sts rx_count,r30

 

ld r30,Y+ ;similar epilogue style as cv
out SREG,r30
ld r30,Y+ ;last memory instruction
reti

 

.global dec_count

dec_count:
lds r30,rx_count
subi r30,1
sts rx_count,r30
ret

 

.global test

test:
lds r30,rx_count
cpi r30,0
breq 1f
rcall dec_count ;breakpoint here, should get here if working correctly
1:
;nop ;fixer
rjmp test

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

Thanks for your comments.

1.  I can replace NOP in #109 with any instruction e.g. SEI, CLT, ...

2.  I can omit the NOP but replace RJMP PC-0x0008 with JMP PC-0x0008

3.  Either way works on the 32E5.   32A4U always works.

 

4.  Inserting NOP before RETI makes no difference.    CV has always used LD Rx,Y+

5.  According to AS7.0 my 32E5 is Revision B

 

6.  I only possess 128A1, 128A4U, 32A4U, 32E5 Xmegas.   Only the 32E5 misbehaves.

7.  What Xmegas do other readers have?

 

8.  I will try your GCC suggestion.    Both as GCC project and as AVRASM2

 

David.

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

I adjusted your code.  i.e. added a catch-all

.global test

test:
    lds r30,rx_count
    cpi r30,0
    breq 1f
    rcall dec_count ;breakpoint here, should get here if working correctly
1:
    ;nop ;fixer
    rjmp test
    nop
here:
    nop
    rjmp here

If I put a Breakpoint on the RCALL,  it stops reliably.

I always have a Breakpoint on the RJMP here NOP.

 

If I remove the RCALL Breakpoint,  I eventually fall through to the NOP breakpoint.

 

I could wiggle a GPIO or start up the RTC Timer to see how long it takes to fall through.   But fall through it does !!!

 

David.

Pages