Very odd input failure using VPorts.

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

A little forward...

I do a lot of AVR assembly, some for fun, and some for commercial products now.

Have been doing so for 10 years now, and for me it is like a second (and perfect) language.

Most of my projects have been for Mega series, but this last one fits well in an XMega, so I have both 256A and 384D.

 

I have come across the most unusual problem I have ever encountered in my entire AVR life!

Seems input using V-Ports just isn't working as expected.

 

I have stripped down my massive code to just the minimal amount to show the failure.
This is for assembly freaks...

 


////////////////////////////////////////////////////////////////////////////////////////////////////////
////////// SETUP XMEGA IO PORTS
////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <avr/io.h>
.global main
main:

// SETUP VIRTUAL PORTS TO A:0 / D:1
ldi r18,(0x00<<0)|(0x03<<4)
sts PORTCFG_VPCTRLA,r18
#define PINA VPORT0_IN
#define PORTA VPORT0_OUT
#define DDRA VPORT0_DIR
#define PIND VPORT1_IN
#define PORTD VPORT1_OUT
#define DDRD VPORT1_DIR

// SETUP VIRTUAL PORTS TO E:2 / F:3
ldi r18,(0x04<<0)|(0x05<<4)
sts PORTCFG_VPCTRLB,r18
#define PINE VPORT2_IN
#define PORTE VPORT2_OUT
#define DDRE VPORT2_DIR
#define PINF VPORT3_IN
#define PORTF VPORT3_OUT
#define DDRF VPORT3_DIR

// PORTA.7 < INPUT TEST
ldi r18,127
out DDRA,r18

// PORTC > 8 LEDS
ser r18
sts PORTC_DIR,r18

////////////////////////////////////////////////////////////////////////////////////////////////////////
////////// IO FAILURE TEST LOOP
////////////////////////////////////////////////////////////////////////////////////////////////////////
clr r18
TEST:

// THIS FAILS MOST TIMES (V-PORT)
q1:
sbis PINA,7
brne q1
q2:
sbic PINA,7
brne q2

// THIS WORKS ALL THE TIME (REAL PORT)
/*
q1:
lds r18,PORTA_IN
sbrc r18,7
rjmp q1
q2:
lds r18,PORTA_IN
sbrs r18,7
rjmp q2
*/

// SHOW LEDS
sts PORTC_OUT,r18
inc r18

clr r19 // THIS MAKES INPUT PINS FAIL!!!!!

rjmp TEST

 

This very basic loop simply reads a clock pulse on PINA.7 and then displays an 8 bit count on PORTC for each cycle.

The code just waits for the HI then LO transition of PINA.7, then adds a register for display on PORTC.

 

What I noticed was that the input was flaky in my design, so I spent days examining hardware and code.

Eventually I realized that the loop works fine with non virtual ports, but fails (mostly) using a virtual port.

 

Now when I say "mostly", this is the REALLY odd part!!!!!

See that useless line (clr r19)?... comment it out and the loop works.

 

When the input fails, it actually passes both branches at a rate that puts an 85 KHz pulse out on the LSB of PORT C.

How bizarre is that?????

 

And it's not just the "clr r19" that makes V-Port Input fail, it is a random thing completely as the code grows.

 

Now continuing in the twilight zone, if I comment out the V-Port block and go back to standard IO, everything works perfectly!

 

I have been confounded for days on this, almost ready to just go back to Mega AVR on this project, but that 32MHz @ 3.3v is what I want.

 

 

 

Here is what I have done so far to make sure I am not hallucinating here...

 

1) Replaced the XMega (384D) twice.

2) Tried 3 other Xmega types (256 and 64).

3) Verified working IO on a Mega324.

4) Tried new power and multiple clock speeds from 1Mhz to 32Mhz.

5) Read the datasheet to ensure that SBIC and SBIS do actually work on XMega V-Ports.

6) Drank more java, and stayed up much later than normal.

 

So far I am stumped!

I do need to use V-Ports here as this project will eventually interface to an FPGA so every cycles means something to me.

 

 

I would sure be happy if someone could point to some obvious head smacking thing I just overlooked.

 

Cheers!

Brad

 

 

 

This topic has a solution.

I Like to Build Stuff : http://www.AtomicZombie.com

Last Edited: Sun. Jul 21, 2019 - 05:04 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
// THIS FAILS MOST TIMES (V-PORT)
q1:
sbis PINA,7
rjmp q1      ;brne q1
q2:
sbic PINA,7
rjmp q2      ;brne q2
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh man, it was indeed a face smacking problem!

I must have read those lines a hundred times and not seen the obvious error.

 

Originally I was reading the entire port into a reg and then ANDing, so the BRNE was used.

That of course, does not excuse me from this public shaming!

 

More proof that...

 

1) A fresh set of eyes is often the most powerful debugging tool you can utilize.

2) This community continues to be the reason that AVR is always my first choice.

 

Thanks!

Brad

I Like to Build Stuff : http://www.AtomicZombie.com

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

Besides "brne q1/q2" being corrected by agentXMEGA already, there are some other pitfalls in your test program.

 

I rewrote your program using s'AVR syntax*:

clr	r18
LOOP	; test loop forever

	; check pins directly
	; for most effective code if no assembly lines are in-between the structure:

	REPEAT
	UNTIL %PINA,7

	REPEAT
	UNTIL NOT %PINA,7

	; using register r18
	; note: using same register for pin test and LEDs might not be a good idea
	; then at least push/pop r18 during the test or use a different register

	REPEAT
		lds r18,PORTA_IN
	UNTIL r18,7

	REPEAT
		lds r18,PORTA_IN
	UNTIL NOT r18,7

	// SHOW LEDS
	sts PORTC_OUT,r18
	inc r18			; this makes troubles when reaching 128
ENDL

The flat AVR assembly being generated by the pre-compiler looks as follows:

clr	r18
	;01// LOOP	; test loop forever
_L1:

	; check pins directly
	; for most effective code if no assembly lines are in-between the structure:

	;02// REPEAT
_L4:
	;02// UNTIL %PINA,7
	SBIS	PINA,7
	RJMP	_L4

	;02// REPEAT
_L7:
	;02// UNTIL NOT %PINA,7
	SBIC	PINA,7
	RJMP	_L7

	; using register r18
	; note: using same register for pin test and LEDs might not be a good idea
	; then at least push/pop r18 during the test or use a different register

	;02// REPEAT
_L10:
	lds r18,PORTA_IN
	;02// UNTIL r18,7
	SBRS	r18,7
	RJMP	_L10

	;02// REPEAT
_L13:
	lds r18,PORTA_IN
	;02// UNTIL NOT r18,7
	SBRC	r18,7
	RJMP	_L13

	// SHOW LEDS
	sts PORTC_OUT,r18
	inc r18
	;01// ENDL
	RJMP	_L1

; s'AVR lines read: 28
; Lines generated: 59
; Errors detected: 0
; Warnings/Hints noted: 0

You will see that the behaviour of the test using a register now is the same (checking for a HIGH pulse).

 

Here is a little s'AVR example for 6 walking LEDs (which also checks a pin status, but to change direction): http://led-treiber.de/html/led-l...

 

If you are interested in s'AVR (it's free), please send me a PN.

I'm sure, you will write more reliable (structured) AVR assembly code in much less time!

 

* English s'AVR manual see here: http://led-treiber.de/html/leds_...

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

Thanks for the response.

All is well now, and my error was just due to lack of sleep, not experience.

 

This is just one part of a motion control system I am working on, interfacing with an FPGA.

My XMega code (pure assembly) is many hundreds of lines long, and works fine now that my proof-reading issue has been resolved.

The XMega here even generates VGA all in software, adding a display to this massive project.

 

I find XMega to be a great uC to partner with an FPGA as they are both blazingly fast (when AVR is coded in pure assembly).

 

Here are some older projects I did, mixing AVR with FPGA to make something cool....

 

https://www.youtube.com/watch?v=GrsY4SpFpHs

 

https://www.youtube.com/user/LucidScience/videos

 

Sometimes you can do amazing things with XMega alone.

XMega + ASM always equals amazing speed and processing power...

 

https://www.youtube.com/watch?v=CXFOTpM2Jn4

 

I did that one in 2011, so it's a bit crude, but the XMega does manage to bit bang full NTSC color and stereo sound.

 

On a side note, that last video posted was a 5 year long experiment in overclocking.

I am running the XMega at 57.636Mhz, which is noting considering they all run stable at 64MHz easily.

In order to prove my point, I ran that demo non stop in my lab for 5 years continuously.

I still have the board, and it still works perfectly after 43,800+ hours of operation!

 

Anyhow, thanks for helping my adjust my glasses.

Still can't believe I missed that wrong instruction after so many reviews.

... hiding in plain sight!

 

Brad

 

 

 

 

 

 

I Like to Build Stuff : http://www.AtomicZombie.com

Last Edited: Sun. Jul 21, 2019 - 02:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AtomicZombie wrote:
XMega + ASM always equals amazing speed and processing power...

It is truth!!!