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.